Solaris のシステム管理 (第 2 巻)

第 35 章 プロセスの管理手順

この章では、システムプロセスを管理する手順について説明します。この章で説明する手順は次のとおりです。

プロセスに関する情報の表示

この節では、プロセス情報を管理するために使用されるコマンドについて説明します。

ps コマンド

ps コマンドを使用すると、システム上で活動中のプロセスの状態をチェックできます。また、プロセスについての技術的な情報も表示できます。このデータは、プロセスの優先順位をどのように設定するか判断するなどの管理作業に利用できます。

ps コマンドを使用すると、システム上で活動中のプロセスの状態をチェックできます。使用するオプションに応じて、次の情報が表示されます。

表 35-1 は、ps コマンドで表示されるフィールドの一部を示しています。どのフィールドが表示されるかは、選択するオプションによって異なります。使用可能なすべてのオプションについては、ps(1) のマニュアルページを参照してください。

表 35-1 ps により出力されるフィールド

フィールド 

説明 

UID

プロセス所有者の実効ユーザー ID 

PID

プロセスの識別番号 

PPID

親プロセスの識別番号 

C

スケジューリングのためのプロセッサ使用率。このフィールドは -c オプションを使用すると表示されない

CLS

プロセスが所属するスケジューリングクラス。リアルタイム、システム、またはタイムシェアリングのいずれか。このフィールドは、-c オプションを指定した場合にのみ表示される

PRI

カーネルスレッドのスケジューリング優先順位。番号が大きいほど優先順位が高い 

NI

プロセスの nice 番号。これは、スケジュール優先順位に影響する。プロセスの nice 番号を大きくすると、その優先順位が下がる

ADDR

proc 構造体のアドレス

SZ

プロセスの仮想アドレスサイズ 

WCHAN

プロセスが休眠中のイベントまたはロックのアドレス 

STIME

プロセスの起動時刻 (時、分、秒) 

TTY

プロセス (またはその親プロセス) が起動された端末。疑問符は、制御端末がないことを示す 

TIME

プロセスの起動以降に使用した合計 CPU 時間 

CMD

プロセスを生成したコマンド 

プロセスを表示する方法

システム上で実行中のすべてのプロセスを表示するには、ps コマンドを使用します。


$ ps [-ef]

ps

ログインセッションに関連するプロセスのみを表示する 

-ef

システム上で実行中のすべてのプロセスに関する詳細情報を表示する 

例 - プロセスを表示する

次の例は、オプションを指定しないときの ps コマンドからの出力を示します。


$ ps
  PID  TTY      TIME COMD
  1664 pts/4    0:06 csh
  2081 pts/4    0:00 ps

次の例は、ps -ef の出力を示します。この例は、システムのブート時に最初に実行されたプロセスが sched (スワッパ) であり、それに続いて init プロセス、pageout の順に実行されたことを示しています。


$ ps -ef
     UID   PID  PPID  C    STIME TTY     TIME CMD
    root     0     0  0   May 05 ?       0:04 sched
    root     1     0  0   May 05 ?      10:48 /etc/init -
    root     2     0  0   May 05 ?       0:00 pageout
    root     3     0  0   May 05 ?      43:21 fsflush
    root   238     1  0   May 05 ?       0:00 /usr/lib/saf/sac -t 300
    root   115     1  0   May 05 ?       0:10 /usr/sbin/rpcbind
    root   158     1  0   May 05 ?       0:00 /usr/lib/autofs/autom...
    root   134     1  0   May 05 ?       0:12 /usr/sbin/inetd -s
    root   107     1  0   May 05 ?      11:49 /usr/sbin/in.routed -q
    root   117     1  5   May 05 ?     899:32 /usr/sbin/keyserv
    root   125     1  0   May 05 ?       0:00 /usr/sbin/kerbd
    root   123     1  0   May 05 ?       4:17 /usr/sbin/nis_cachemgr
    root   137     1  0   May 05 ?       0:00 /usr/lib/nfs/statd
    root   139     1  0   May 05 ?       0:02 /usr/lib/nfs/lockd
    root   159     1 50   May 05 ?    8243:36 /usr/sbin/automount
    root   162     1  0   May 05 ?       0:07 /usr/sbin/syslogd
    root   181     1  0   May 05 ?       0:03 /usr/sbin/nscd... 
    root   169     1  0   May 05 ?       5:09 /usr/sbin/cron
    root   191     1  0   May 05 ?       0:00 /usr/lib/lpsched
    root   210     1  0   May 05 ?       0:01 /usr/sbin/vold
    root   200     1  0   May 05 ?       0:08 /usr/lib/sendmail -bd -q1h
    root  4942     1  0   May 17 console 0:00 /usr/lib/saf/ttymon...
    root   208     1  0   May 05 ?       0:00 /usr/lib/utmpd
    root   241   238  0   May 05 ?       0:00 /usr/lib/saf/ttymon
    root  5748   134  0 17:09:49 ?       0:01 in.rlogind
    root  5750  5748  0 17:09:52 pts/0   0:00 -sh
    root  5770  5750  2 17:23:39 pts/0   0:00 ps -ef

/proc ファイルシステムとコマンド

/usr/proc/bin ディレクトリ内のプロセスツールを使用すると、/proc にあるプロセスに関して詳細情報を表示できます。/proc ディレクトリは、プロセスファイルシステム (PROCFS) とも呼ばれます。アクティブなプロセスのイメージは、そのプロセス ID 番号を使って /proc に格納されます。

プロセスツールは ps コマンドの一部のオプションに似ていますが、このツールから提供される出力の方が詳細です。一般に、プロセスツールには次の機能があります。

プロセスに関する情報の表示 (/proc ツール)

/usr/proc/bin に入っているプロセスツールコマンドを使用すると、活動中のプロセスに関する詳細な技術情報を表示できます。表 35-2 は、これらのプロセスツールを示しています。詳細は、proc(1) のマニュアルページを参照してください。

表 35-2 情報を表示する /usr/proc/bin のプロセスツール

プロセスツール 

表示される内容 

pcred

資格 

pfiles

プロセス内で開いているファイルに関する fstat 情報と fcntl 情報

pflags

/proc 追跡フラグ、保留状態のシグナルと保持状態のシグナル、他の状態情報

pldd

プロセスにリンクされた動的ライブラリ 

pmap

アドレス空間マップ 

psig

シグナルの動作 

pstack

16 進 + シンボリックスタックトレース 

ptime

microstate アカウンティングを使用するプロセス時間

ptree

プロセスが入っているプロセスツリー 

pwait

プロセス終了後の状態情報 

pwdx

プロセスの現在の作業ディレクトリ 


注 -

長いコマンド名を入力しなくてもすむように、プロセスツールディレクトリを PATH 変数に追加してください。これにより、各ファイル名の最後の部分 (たとえば、/usr/proc/bin/pwdx ではなく pwdx) を入力するだけで、プロセスツールを実行できます。


プロセスに関する情報を表示する方法

  1. (省略可能) pgrep コマンドからの出力を使用して、詳細情報を表示したいプロセスの識別番号を調べます。


    # pgrep process
    

    process

    詳細情報を表示したいプロセス名 

    プロセス識別番号は、出力の第 1 列目に表示されます。

  2. 適切な /usr/proc/bin コマンドを使用して必要な情報を表示します。


    # /usr/proc/bin/pcommand PID
    

    pcommand

    実行したいプロセスツールコマンド。表 35-2 を参照

    PID

    プロセスの識別番号 

例 - プロセスに関する情報を表示する

次の例は、プロセスツールコマンドを使用して lpsched プロセスに関する詳細情報を表示する方法を示しています。まず、長いプロセスツールコマンドを入力しなくてもすむように、/usr/proc/bin パスが定義されています。次に、lpsched の識別番号が表示されています。最後に、3 つのプロセスツールコマンドからの出力が表示されています。


# PATH=$PATH:/usr/proc/bin
# export PATH 1
# ps -e | grep lpsched 2
207 ?        0:00 /usr/lib/lpsched
# pwdx 207 3
207:    /
# ptree 207 4
207   /usr/lib/lpsched
# pfiles 207 5
207:    /usr/lib/lpsched
  Current rlimit: 4096 file descriptors
   0: S_IFIFO mode:0000 dev:179,0 ino:70 uid:0 gid:0 size:0
      O_RDWR
   1: S_IFIFO mode:0000 dev:179,0 ino:70 uid:0 gid:0 size:0
      O_RDWR
   3: S_IFCHR mode:0666 dev:32,8 ino:11446 uid:0 gid:3 rdev:21,0
      O_WRONLY FD_CLOEXEC
   4: S_IFDOOR mode:0444 dev:183,0 ino:59515 uid:0 gid:0 size:0
      O_RDONLY|O_LARGEFILE FD_CLOEXEC  door to nscd[201]
   5: S_IFREG mode:0664 dev:32,9 ino:1330 uid:71 gid:8 size:0
      O_WRONLY
  1. /usr/proc/bin ディレクトリを PATH 変数に追加します。

  2. lpsched のプロセス識別番号を表示します。.

  3. lpsched の現在の作業ディレクトリを表示します。.

  4. lpsched が入っているプロセスツリーを表示します。.

  5. fstatfcntl の情報を表示します。

次の例は、pwait コマンドからの出力を示しています。このコマンドは、プロセスが終了するまで待ってから、発生した処理に関する情報を表示します。次の例は、コマンドツールウィンドウを閉じた後の pwait コマンドからの出力を示しています。


$ ps -e | grep cmdtool
  273 console 0:01 cmdtool
  277 console 0:01 cmdtool
  281 console 0:01 cmdtool
$ pwait -v 281
281: terminated, wait status 0x0000

プロセスの制御 (/proc ツール)

/usr/proc/bin に入っているプロセスツールを使用すると、プロセスの一部を制御できます。表 35-3 に、これらのプロセスツールを示します。詳細は、proc(1) のマニュアルページを参照してください。

表 35-3 プロセスツール

ツールの種類 

ツールの機能または表示内容 

/usr/proc/bin/pstop pid

プロセスを停止する 

/usr/proc/bin/prun pid

プロセスを再開する 

/usr/proc/bin/ptime pid

microstate アカウントを使用してプロセスの時間を測定する

/usr/proc/bin/pwait [-v] pid

指定されたプロセスが終了するのを待つ 

 

プロセスの詳細を表示するツール 

/usr/proc/bin/pcred pid

資格 

/usr/proc/bin/pfiles pid

開いたファイルの fstat 情報と fcntl 情報

/usr/proc/bin/pflags pid

/proc の追跡フラグ、保留シグナルと保持シグナル、lwp ごとの他の状態情報

/usr/proc/bin/pldd pid

各プロセスにリンクされた動的ライブラリ 

/usr/proc/bin/pmap pid

アドレス空間マップ 

/usr/proc/bin/psig pid

シグナルの動作 

/usr/proc/bin/pstack pid

lwp ごとの 16 進数 + 記号スタックトレース

/usr/proc/bin/ptree pid

指定した pid が入ったプロセスツリー

/usr/proc/bin/pwdx pid

現在の作業ディレクトリ 

上記の表 35-3 で、pid はプロセス識別番号です。この番号は ps -ef コマンドを使用して表示できます。

第 35 章「プロセスの管理手順」では、プロセスツールコマンドを使用して、プロセスの詳細表示や、プロセスの起動および終了などのシステム管理作業を実行する方法を説明します。プロセスツールのさらに詳細な説明は、proc(1) のマニュアルページを参照してください。

プロセスが無限ループ内でトラップされた場合や、実行時間が長すぎる場合は、プロセスを終了 (kill) できます。pkill コマンドを使用してプロセスを終了する方法については、第 35 章「プロセスの管理手順」を参照してください。

以前のフラットな /proc ファイルシステムは、状態情報と制御機能のためのサブディレクトリが追加されたディレクトリ階層に再構築されました。

/proc ファイルシステムは、ウォッチポイント機能も提供します。この機能は、プロセスのアドレス領域の個々のページの読み取り権または書き込み権を再マップするために使用されます。この機能は制限がなく、MT-safe です。

新しい /proc ファイル構造は、古い /proc インタフェースと完全なバイナリ互換を提供します。ただし、新しいウォッチポイント機能は、古いインタフェースでは使用できません。

デバッグ用ツールは、/proc の新しいウォッチポイント機能を使用するように変更されています。つまり、ウォッチポイントプロセス全体がより高速になったためです。

dbx デバッグ用ツールを使用してウォッチポイントを設定するときの次の制限は取り除かれました。

詳細は、proc(4)core(4)、および adb(1) のマニュアルページを参照してください。


注 -

長いコマンド名を入力しなくてもすむように、プロセスツールディレクトリを PATH 変数に追加してください。これにより、各ファイル名の最後の部分 (たとえば、/usr/proc/bin/prun ではなく prun) を入力するだけで、プロセスツールを実行できます。


プロセスを制御する方法

  1. (省略可能) ps コマンドからの出力を使用して、詳細情報を表示したいプロセスの識別番号を調べます。


    # pgrep process
    

    process

    詳細情報を表示したいプロセス名 

    プロセス識別番号は、出力の第 1 列目に表示されます。

  2. 適切な /usr/proc/bin コマンドを使用してプロセスを制御します。


    # /usr/proc/bin/pcommand PID
    

    pcommand

    実行したいプロセスツールコマンド。これらのコマンドについては、表 35-3 を参照

    PID

    プロセスの識別番号 

  3. ps コマンドで、プロセスの状態を確認します。


    # ps | grep PID
    

例 - プロセスを制御する

次の例は、プロセスツールを使用して印刷ツールを停止したり、再起動したりする方法を示しています。


# PATH=$PATH:/usr/proc/bin
# export PATH
# ps -e | grep 'print*'
264 console 0:03 printtool
# pstop 264
# prun 264
# ps | grep 264
264 console 0:03 printtool
#
  1. /usr/proc/bin ディレクトリを PATH 変数に追加します。

  2. 印刷ツールのプロセス識別番号を表示します。

  3. 印刷ツールプロセスを停止します。

  4. 印刷ツールプロセスを再開します。

プロセスの終了 (pkill)

プロセスを強制的に終了 (kill) させなければならない場合があります。プロセスが無限ループに入っていたり、大きいジョブを開始したが完了する前に停止したい場合があります。所有しているプロセスであれば、どれでも終了できます。また、スーパーユーザーはプロセス ID が 01234 のものを除き、システム上のどんなプロセスでも終了できます。

詳細は、pkill(1) のマニュアルページを参照してください。

プロセスを終了させる方法

  1. (省略可能) 別のユーザーが所有するプロセスを終了するには、スーパーユーザーになります。

  2. (省略可能) pgrep コマンドからの出力を使用して、詳細情報を表示したいプロセスの識別番号を表示します。


    $ pgrep process
    

    process

    詳細情報を表示したいプロセス名 

    プロセスの識別番号は、出力の第 1 列目に表示されます。

  3. pkill コマンドを使用してプロセスを終了します。


    $ pkill [-9] PID ...

    -9

    プロセスを確実に終了させる 

    PID . . .

    停止する 1 つ以上のプロセスの ID  

  4. pgrep コマンドを使用して、プロセスが停止したことを確認します。


    $ pgrep PID ...

プロセスクラス情報の管理

次のリストは、システム上で構成されるクラスと、タイムシェアリングクラスのユーザー優先順位の範囲です。クラスの種類は次のとおりです。

priocntl を使用してプロセスのスケジュール優先順位を変更する

プロセスのスケジュール優先順位とは、プロセススケジューラによって割り当てられる優先順位のことです。これらの優先順位は、スケジューラのスケジュールポリシーに従って割り当てられます。dispadmin コマンドを使用すると、デフォルトのスケジュールポリシーを表示できます。dispadmin コマンドの使用方法については、「プロセスの優先順位を指定する方法」を参照してください。

priocntl(1) コマンドを使用すると、プロセスを優先順位クラスに割り当て、プロセスの優先順位を管理できます。プロセスを管理するための priocntl コマンドの使用方法については、「プロセスの優先順位を指定する方法」を参照してください。

プロセスクラスに関する基本情報を表示する方法

priocntl -l コマンドを使用すると、プロセスクラスとスケジューリングパラメタを表示できます。


$ priocntl -l

例 - プロセスクラスに関する基本情報を表示する

次の例に priocntl -l コマンドからの出力を示します。


# priocntl -l
CONFIGURED CLASSES
==================

SYS (System Class)

TS (Time Sharing)
        Configured TS User Priority Range: -60 through 60

IA (Interactive)
        Configured IA User Priority Range: -60 through 60

RT (Real Time)
        Maximum Configured RT Priority: 59

プロセスのグローバル優先順位を表示する方法

ps コマンドを使用して、プロセスのグローバル優先順位を表示できます。


$ ps -ecl

グローバル優先順位は、PRI カラムの下に表示されます。

例 - プロセスのグローバル優先順位を表示する

次の例は、ps -ecl からの出力を示しています。PRI カラム内のデータは、pageout が最上位の優先順位を持ち、sh が最下位の優先順位であることを示しています。


$ ps -ecl
 F S UID PID  PPID CLS PRI  ADDR      SZ  WCHAN    TTY      TIME   COMD
19 T 0   0    0    SYS 96   f00d05a8   0           ?        0:03  sched
 8 S 0   1    0    TS  50   ff0f4678 185  ff0f4848 ?       36:51   init
19 S 0   2    0    SYS 98   ff0f4018   0  f00c645c ?        0:01 pageout
19 S 0   3    0    SYS 60   ff0f5998   0  f00d0c68 ?      241:01 fsflush
 8 S 0   269  1    TS  58   ff0f5338 303  ff49837e ?        0:07    sac
 8 S 0   204  1    TS  43   ff2f6008  50  ff2f606e console  0:02     sh
 

プロセスの優先順位を指定する方法

  1. スーパーユーザーになります。

  2. 指定した優先順位を持つプロセスを起動します。


    # priocntl -e -c class -m userlimit -p pri command_name
    

    -e

    コマンドを実行する 

    -c class

    プロセスを実行する範囲のクラスを指定する。デフォルトのクラスは TS (タイムシェアリング) または RT (リアルタイム)

    -m userlimit

    -p オプションを使用するときに、優先順位を上下できる最大範囲を指定する

    -p pri command_name

    リアルタイムスレッド用に RT クラス内で相対優先順位を指定できるようにする。タイムシェアリングプロセスの場合は、-p オプションを使用すると -20 から +20 までのユーザー提供の優先順位を指定できる

  3. ps -ecl コマンドで、プロセスの状態を確認します。


    # ps -ecl | grep command_name
    

例 - 優先順位を指定する

次の例では、ユーザーが提供する最上位の優先順位を使用して find コマンドを起動します。


# priocntl -e -c TS -m 20 -p 20 find . -name core -print
# ps -ecl | grep find

タイムシェアリングプロセスのスケジューリングパラメタを変更する方法

  1. スーパーユーザーになります。

  2. 実行中のタイムシェアリングプロセスのスケジューリングパラメタを変更します。


    # priocntl -s -m userlimit [-p userpriority] -i idtype idlist
    

    -s

    ユーザー優先順位の範囲の上限を設定し、現在の優先順位を変更できる 

    -m userlimit

    -p オプションを使用するときに、優先順位を上下できる最大範囲を指定する

    -p userpriority

    優先順位を指定できる 

    -i idtype idlist

    idtypeidlist の組み合わせを使用してプロセスを識別する。idtype では PIDUID など、ID のタイプを指定する

  3. ps -ecl コマンドで、プロセスの状態を確認します。


    # ps -ecl | grep idlist

例 - タイムシェアリングプロセスのスケジューリングパラメタを変更する

次の例では、500 ミリ秒のタイムスライス、クラス RT 内の優先順位 20、グローバル優先順位 120 を指定して、コマンドを実行します。


# priocntl -e -c RT -t 500 -p 20 myprog
# ps -ecl | grep myprog

プロセスのクラスを変更する方法

  1. (省略可能) スーパーユーザーになります。


    注 -

    プロセスをリアルタイムプロセスに変更したり、リアルタイムプロセスから変更したりするには、ユーザーはリアルタイムシェル内でスーパーユーザーであるか、作業中でなければなりません。


  2. プロセスのクラスを変更します。


    # priocntl -s -c class -i idtype idlist
    

    -s

    ユーザー優先順位の範囲について上限を設定し、現在の優先順位を変更できる 

    -c class

    クラス TS またはクラス RT を指定して、プロセスのクラスを変更する

    -i idtype idlist

    idtypeidlist の組み合わせを使用してプロセスを識別する。idtype では PIDUID など、ID のタイプを指定する

  3. ps -ecl コマンドで、プロセスの状態を確認します。


    # ps -ecl | grep idlist
    

例 - プロセスのクラスを変更する

次の例では、ユーザー 15249 が所有するすべてのプロセスをリアルタイムプロセスに変更します。


# priocntl -s -c RT -i uid 15249
# ps -ecl | grep 15249

注 -

スーパーユーザーとしてユーザープロセスをリアルタイムクラスに変更すると、その後ユーザーはリアルタイムのスケジューリングパラメタを (priocntl -s を使用して) 変更できません。


nice を使用してタイムシェアリングプロセスの優先順位を変更する

nice(1) コマンドは、SunOS の旧バージョンとの下位互換性を保つためにのみサポートされます。priocntl コマンドを使用する方がプロセスを柔軟に管理できます。

プロセスの優先順位は、そのスケジュールクラスポリシーと nice number 番号によって決定されます。各タイムシェアリングプロセスは、ユーザーが与えた優先順位を加算して計算されるグローバル優先順位を持っています。これは、nice コマンドまたは priocntl コマンド、およびシステムによって計算される優先順位の影響を受けます。

プロセスの実行優先順位番号は、オペレーティングシステムによって割り当てられ、スケジュールクラス、使用される CPU 時間、nice 値 (タイムシェアリングプロセスの場合) などの複数の要素によって決定されます。

各タイムシェアリングプロセスは、親プロセスから継承したデフォルトの nice 番号で起動します。nice 値は、ps レポートの NI カラムに表示されます。

ユーザーは、自分が与える nice 番号優先順位を大きくしてプロセスの優先順位を下げることができます。ただし、nice 番号を小さくしてプロセスの優先順位を上げることができるのは、スーパーユーザー (または root) だけです。これは、ユーザーが各自のプロセスの優先順位を大きくして CPU の独占比率を高めるのを防ぐためです。

nice 番号の範囲は 0 から +40 までで、0 は最上位の優先順位を与えます。デフォルト値は 20 です。nice コマンドには利用できるバージョンが 2 つあり、一方は標準バージョンの /usr/bin/nice で、他方は C シェルの一部となっているバージョンです。

プロセスの優先順位を変更する方法

nice 番号を変更して、コマンドやプロセスの優先順位を変更できます。プロセスの優先順位を下げるには、次のコマンドを使用します。

/usr/bin/nice command_name

nice 番号を 4 単位で増やす (デフォルト)

/usr/bin/nice +4 command_name

nice 番号を 4 単位で増やす

/usr/bin/nice -10 command_name

nice 番号を 10 単位で増やす

第 1 と第 2 のコマンドは、nice 番号を 4 単位で増やします (デフォルト)。第 3 のコマンドは、nice を 10 単位で増やしていますが負数の増分なので、プロセスの優先順位を下げます。

次のコマンドは、nice 番号を小さくしてコマンドの優先順位を上げます。

プロセスの優先順位を上げるには、次のコマンドを使用します。

/usr/bin/nice -10 command_name

nice 番号を小さくしてコマンドの優先順位を上げる

/usr/bin/nice - -10 command_name

nice 番号を小さくしてコマンドの優先順位を上げる。最初のマイナス記号はオプションの記号で、第 2 のマイナス記号は負の数を示す

上記のコマンドでは、nice 番号を小さくしてコマンド command_name の優先順位を上げます。第 2 のコマンドでは、2 つのマイナス記号が必要なので注意してください。

プロセスの問題解決方法

すでに判明している問題の解決方法のヒントを次に示します。