hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

psコマンドの使い方

1 psコマンドとは?

プロセスの状態を確認するコマンドです。

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

搭載CPU数は4個です。

[root@server ~]# cat /proc/cpuinfo |grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3

搭載メモリ量は4Gです。

[root@server ~]# free
              total        used        free      shared  buff/cache   available
Mem:        3861292      370416     3181612        3660      309264     3248008
Swap:        131068           0      131068

3 プロセスの状態を表示する方法

3.1 コマンド名を表示する方法(comm)

sleepコマンドを実行します。

[root@server ~]# sleep 300&
[2] 2440

プロセスの状態を確認します。COMMAND列がsleepになっていることがわかります。

[root@server ~]# ps -C sleep -o comm
COMMAND
sleep

あと始末をします。

[root@server ~]# kill -9 2440
[root@server ~]#
[2]+  強制終了            sleep 300

3.2 プロセスのPID,PPIDを表示する方法(pid,ppid)

sleepコマンドを実行します。

[root@server ~]# sleep 300&
[1] 2085

プロセスの状態を確認します。PIDはsleepプロセス自身のPID、PPIDはsleepプロセスの親プロセスのPIDを表しています。

[root@server ~]# ps -C sleep -o comm,pid,ppid
COMMAND            PID   PPID
sleep             2085   1965

あと始末をします。

[root@server ~]# kill -9 2085
[root@server ~]#
[1]+  強制終了            sleep 300

3.3 プロセスの仮想メモリサイズ、実メモリサイズを表示する方法(vsz,rss)

sleepコマンドを実行します。

[root@server ~]# sleep 300&
[1] 2096

プロセスの状態を確認します。VSZが仮想メモリサイズ、RSS実メモリサイズを表しています。RSSは、プロセスに割り当てられている実メモリ量を表しています。

[root@server ~]# ps -C sleep -o comm,pid,vsz,rss
COMMAND            PID    VSZ   RSS
sleep             2096 108052   356

あと始末をします。

[root@server ~]# kill -9 2096
[root@server ~]#
[1]+  強制終了            sleep 300

3.4 コマンドの実行時刻を表示する方法(lstart)

sleepコマンドを実行します。

[root@server ~]# date;sleep 300 &
2022年  5月 15日 日曜日 21:14:52 JST
[1] 2100

プロセスの状態を確認します。sleepコマンドの実行時刻が、21:14:51 であることがわかります。

[root@server ~]# ps -C sleep -o comm,pid,lstart
COMMAND            PID                  STARTED  START
sleep             2100 Sun May 15 21:14:51 2022  21:14

あと始末をします。

[root@server ~]# kill -9 2100
[root@server ~]#
[1]+  強制終了            sleep 300

3.5 コマンド実行開始からの経過時間を表示する方法(etime)

sleepコマンドを実行します。

[root@server ~]# date;sleep 300 &
2022年  5月 15日 日曜日 21:32:20 JST
[1] 2154

プロセスの状態を確認します。sleepコマンドを実行してから8秒経過していることがわかります。

[root@server ~]#  date;ps -C sleep -o comm,pid,etime
2022年  5月 15日 日曜日 21:32:27 JST
COMMAND            PID     ELAPSED
sleep             2154       00:08

あと始末をします。

[root@server ~]# kill -9 2154
[root@server ~]#
[1]+  強制終了            sleep 300

3.6 CPU使用率を表示する方法(%cpu)

プロセスのCPU使用率が10%になるように、stress-ngコマンドを実行します。なお、stress-ngコマンドのインストール方法、使い方は、stress-ngコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# stress-ng -k -c 1 -l 10 -q &
[1] 2181

プロセスの状態を確認します。stress-ngプロセスのCPU使用率が10.2%であることがわかります。stress-ngコマンドで指定したCPU使用率におおよそ等しいことがわかります。

[root@server ~]# ps -C stress-ng -o comm,pid,ppid,wchan,%cpu
COMMAND            PID   PPID WCHAN  %CPU
stress-ng         2181   1965 do_wai  0.0
stress-ng         2182   2181 poll_s 10.2

あと始末をします。

[root@server ~]# pkill stress-ng
[root@server ~]#
[1]+  終了                  stress-ng -k -c 1 -l 10 -q

3.7 メモリ使用率を表示する方法(%mem)

搭載メモリ量を確認します。3861292(KB)であることがわかります。

[root@server ~]# free -k
              total        used        free      shared  buff/cache   available
Mem:        3861292      405288     3189320        3692      266684     3212048
Swap:        131068           0      131068
  • 256Mのメモリを獲得した場合

256Mのメモリを獲得するように、stressコマンドを実行します。なお、stressコマンドのインストール方法、使い方は、stressコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# stress -m 1 --vm-bytes 268435456 --vm-hang 0 -q &

プロセスの状態を確認します。搭載メモリの6.7%を使用していることがわかります。

[root@server ~]# ps -C stress -o comm,pid,ppid,%mem,rss
COMMAND            PID   PPID %MEM   RSS
stress            2346   1960  0.0   428
stress            2347   2346  6.7 262296

搭載メモリ(3861292KB)の6.7%は、およそ252Mであることがわかります。stressコマンドで獲得した物理メモリ量におおよそ等しいことがわかります。

[root@server ~]# bc -q
3861292*0.067
258706.564

あと始末をします。

[root@server ~]# pkill stress
[1]+  Terminated              stress -m 1 --vm-bytes 268435456 --vm-hang 0 -q
  • 128Mのメモリを獲得した場合

128Mのメモリを獲得するように、stressコマンドを実行します。

[root@server ~]# stress -m 1 --vm-bytes 134217728 --vm-hang 0 -q &

プロセスの状態を確認します。搭載メモリの3.3%を使用していることがわかります。

[root@server ~]# ps -C stress -o comm,pid,ppid,%mem,rss
COMMAND            PID   PPID %MEM   RSS
stress            2391   1960  0.0   428
stress            2392   2391  3.3 131216

搭載メモリ(3861292KB)の3.3%は、およそ124Mであることがわかります。stressコマンドで獲得した物理メモリ量におおよそ等しいことがわかります。

[root@server ~]# bc -q
3861292*0.033
127422.636

あと始末をします。

[root@server ~]# pkill stress
[1]+  Terminated              stress -m 1 --vm-bytes 134217728 --vm-hang 0 -q

3.8 プロセスがスリープしている関数を表示する方法(wchan)

sleepコマンドを実行します。

[root@server ~]#  sleep 300&
[1] 2285

sleepプロセスは、hrtimer_nanosleep関数を呼び出してスリープ(S列がS)していることがわかります。

[root@server ~]# ps -C sleep -o comm,pid,state,wchan
COMMAND            PID S WCHAN
sleep             2285 S hrtimer_nanosleep

参考までに、以下にhrtimer_nanosleep関数を抜粋します。hrtimer_nanosleep関数は、kernel/hrtimer.cで定義されています。

long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
                       const enum hrtimer_mode mode, const clockid_t clockid)
{
        struct restart_block *restart;
        struct hrtimer_sleeper t;
        int ret = 0;
        unsigned long slack;

        slack = current->timer_slack_ns;
        if (dl_task(current) || rt_task(current))
                slack = 0;

        hrtimer_init_on_stack(&t.timer, clockid, mode);
        hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
        if (do_nanosleep(&t, mode))
                goto out;

        /* Absolute timers do not update the rmtp value and restart: */
        if (mode == HRTIMER_MODE_ABS) {
                ret = -ERESTARTNOHAND;
                goto out;
        }

        if (rmtp) {
                ret = update_rmtp(&t.timer, rmtp);
                if (ret <= 0)
                        goto out;
        }

        restart = &current_thread_info()->restart_block;
        restart->fn = hrtimer_nanosleep_restart;
        restart->nanosleep.clockid = t.timer.base->clockid;
        restart->nanosleep.rmtp = rmtp;
        restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);

        ret = -ERESTART_RESTARTBLOCK;
out:
        destroy_hrtimer_on_stack(&t.timer);
        return ret;
}

3.9 プロセスが動作しているCPUを表示する方法(psr)

sleepコマンドを実行します。このとき、tasksetコマンドを使って、sleepプロセスをCPU0で動作させます。なお、tasksetコマンドのインストール方法、使い方は、tasksetコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# taskset -c 0 sleep 300&
[1] 2327

プロセスの状態を確認します。sleepプロセスがCPU0で動作していることがわかります。

[root@server ~]# ps -C sleep -o comm,pid,psr
COMMAND            PID PSR
sleep             2327   0

後始末をします。

[root@server ~]# kill -9 2327
[root@server ~]#
[1]+  強制終了            taskset -c 0 sleep 300

次に、sleepプロセスをCPU2で動作させます。

[root@server ~]# taskset -c 2 sleep 300&
[1] 2357

プロセスの状態を確認します。sleepプロセスがCPU2で動作していることがわかります。

[root@server ~]# ps -C sleep -o comm,pid,psr
COMMAND            PID PSR
sleep             2357   2

後始末をします。

[root@server ~]# kill -9 2357
[root@server ~]#
[1]+  強制終了            taskset -c 2 sleep 300

3.10 スレッドIDを表示する方法(lwp,spid,tid)

スレッドIDを表示するためのオプションとして、lwp,spid,tidがあります。spid, tidはlwpの別名です。

テストプログラムを作成します。

[root@server ~]# vi tp.c
[root@server ~]# cat tp.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>

void *threadFunc1(void)
{
    int fd;
    struct timespec req;
    char str[] = "0123456789";

    req.tv_sec = 300;
    req.tv_nsec = 0;

    for(;;) {
        fd = open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);

        write(fd, str, (size_t)sizeof(str));
        close(fd);

        nanosleep(&req, NULL);
    }
}

int main(int argc, char *argv[])
{
    pthread_t t1;
    void *res;

    pthread_create(&t1, NULL, (void *)&threadFunc1, NULL);

    pthread_join(t1, &res);
    exit(0);
}

テストプログラムをコンパイルします。

[root@server ~]# gcc -Wall -pthread -o tp tp.c

テストプログラムを実行します。

[root@server ~]# ./tp

プロセスの状態を確認します。このテストプログラムを実行すると、プロセスが1つ(PID=2571)、スレッドが2つ(LWP=2571,2572)生成されることがわかります。

[root@server ~]# ps -LC tp -o comm,pid,lwp,spid,tid,wchan
COMMAND            PID    LWP   SPID    TID WCHAN
tp                2571   2571   2571   2571 futex_wait_queue_me
tp                2571   2572   2572   2572 hrtimer_nanosleep

4 プロセスのスケジューリング・ポリシー、優先度を表示する方法

4.1 リアルタイムプロセスの場合(rtprio)

テストプログラムを作成します。

[root@server ~]# vi rt.c
[root@server ~]# cat rt.c
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    struct sched_param sp;
    int policy;

    if(argv[1][0] == 'r')
        policy = SCHED_RR ;
    else if (argv[1][0] == 'f')
        policy = SCHED_FIFO ;
    else {
        fprintf(stderr, "Error\n") ;
        exit(1);
    }

    sp.sched_priority = atoi(argv[2]);
    printf("policy=%d,priority=%d\n", policy,sp.sched_priority);

    sched_setscheduler(0, policy, &sp);
    sleep(60*10) ;

    return 0;
}

テストプログラムをコンパイルします。

[root@server ~]# gcc -Wall -o rt rt.c
  • SCHED_FIFOの場合
[root@server ~]# ./rt f 10
policy=1,priority=10

プロセスの状態を確認します。プロセスのスケジューリング・ポリシー(CLS列)がSCHED_FIFO(FF)、優先度(RTPRIO列)が10であることがわかります。

[root@server ~]# ps -C rt -o comm,cls,rtprio
COMMAND         CLS RTPRIO
rt               FF     10
  • SCHED_RRの場合
[root@server ~]# ./rt r 99
policy=2,priority=99

プロセスの状態を確認します。プロセスのスケジューリング・ポリシー(CLS列)がSCHED_RR(RR)、優先度(RTPRIO列)が99であることがわかります。

[root@server ~]# ps -C rt -o comm,cls,rtprio
COMMAND         CLS RTPRIO
rt               RR     99
  • watchdogプロセスの場合

watchdogプロセスの優先度を確認してみます。watchdogプロセスは、SCHED_FIFO、優先度が99であることがわかります

[root@server ~]# ps -C watchdog/0 -o comm,cls,rtprio
COMMAND         CLS RTPRIO
watchdog/0       FF     99

4.2 タイムスライスプロセスの場合(ni)

テストプログラムを作成します。なお、タイムスライスプロセスは、カーネルソースコードでは、SCHED_OTHER というマクロで定義されています。

[root@server ~]# vi ts.c
[root@server ~]# cat ts.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>

int main(int argc, char *argv[])
{
    int nice;

    printf("Initial nice value is %d\n", getpriority(0, 0)) ;

    setpriority(0, 0, atoi(argv[1]));
    nice = getpriority(0, 0) ;
    printf("nice value is %d\n", nice) ;

    sleep(60*10) ;
    return 0;
}

テストプログラムをコンパイルします。

[root@server ~]# gcc -Wall -o ts ts.c
  • 最高優先度(NICE値=-20)

プロセスのNICE値が-20になるようにテストプログラムを実行します。NICE値-20は、スケジューリングポリシーがSCHED_OTHERの中で最高優先度になります。

[root@server ~]# ./ts -20
Initial nice value is 0
nice value is -20

プロセスの状態を確認します。プロセスのスケジューリング・ポリシー(CLS列)がタイムスライス(TS)、NICE値が-20であることがわかります。

[root@server ~]# ps -C ts -o comm,cls,ni
COMMAND         CLS  NI
ts               TS -20
  • デフォルト値の場合(NICE値=0)

プロセスのNICE値が0になるようにテストプログラムを実行します。

[root@server ~]# ./ts 0
Initial nice value is 0
nice value is 0

プロセスの状態を確認します。プロセスのスケジューリング・ポリシー(CLS列)がタイムスライス(TS)、NICE値が0であることがわかります。

[root@server ~]# ps -C ts -o comm,cls,ni
COMMAND         CLS  NI
ts               TS   0
  • 最低優先度の場合(NICE値=19)

プロセスのNICE値が19になるようにテストプログラムを実行します。NICE値19は、スケジューリングポリシーがSCHED_OTHERの中で最低優先度になります。

[root@server ~]# ./ts 19
Initial nice value is 0
nice value is 19

プロセスの状態を確認します。プロセスのスケジューリング・ポリシー(CLS列)がタイムスライス(TS)、NICE値が19であることがわかります。

[root@server ~]# ps -C ts -o comm,cls,ni
COMMAND         CLS  NI
ts               TS  19

5 ソートする方法(--sort Keyword)

--sortオプションを使うと、プロセスのCPU使用率やメモリ使用量(rss)等を昇順、降順に並べ替えることができます。

5.1 CPU使用率を昇順、降順に表示する方法

プロセスのCPU使用率が10%,20%,30%になるようにstress-ngコマンドを実行します。

[root@server ~]# stress-ng -k -c 1 -l 10 -q &
[1] 2710
[root@server ~]# stress-ng -k -c 1 -l 20 -q &
[2] 2712
[root@server ~]# stress-ng -k -c 1 -l 30 -q &
[3] 2714

CPU使用率を降順に表示してみます。

[root@server ~]# ps -C stress-ng -o comm,%cpu --sort -%cpu
COMMAND         %CPU
stress-ng       29.9
stress-ng       19.8
stress-ng       10.3
stress-ng        0.0
stress-ng        0.0
stress-ng        0.0

CPU使用率を昇順に表示してみます。

[root@server ~]# ps -C stress-ng -o comm,%cpu --sort +%cpu
COMMAND         %CPU
stress-ng        0.0
stress-ng        0.0
stress-ng        0.0
stress-ng        9.9
stress-ng       20.0
stress-ng       29.8

stress-ngプロセス以外のプロセスも含めて、CPU使用率を降順に表示してみます。

[root@server ~]# ps ax -o comm,%cpu --sort -%cpu |head -n 10
COMMAND         %CPU
stress-ng       29.9
stress-ng       19.9
stress-ng       10.1
vmtoolsd         0.1
systemd          0.0
kthreadd         0.0
kworker/0:0H     0.0
ksoftirqd/0      0.0
migration/0      0.0

後始末をします。

[root@server ~]# pkill stress-ng
[root@server ~]#
[1]   終了                  stress-ng -k -c 1 -l 10 -q
[2]-  終了                  stress-ng -k -c 1 -l 20 -q
[3]+  終了                  stress-ng -k -c 1 -l 30 -q

5.2 メモリ使用量を昇順、降順に表示する方法

プロセスが獲得する実メモリサイズが128Mになるようにstressコマンドを実行します。
なお、stressコマンドのインストール、使い方は、stressコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# stress -m 1 --vm-bytes 134217728 --vm-hang 0 -q &
[1] 2795

プロセスが獲得する実メモリサイズが64Mになるようにstressコマンドを実行します。

[root@server ~]# stress -m 1 --vm-bytes 67108864 --vm-hang 0 -q &
[2] 2797

メモリ使用量を降順に表示してみます。

[root@server ~]# ps -C stress -o comm,pid,rss --sort -rss
COMMAND            PID   RSS
stress            2796 131212
stress            2798 65544
stress            2797   428
stress            2795   424

メモリ使用量を昇順に表示してみます。

[root@server ~]# ps -C stress -o comm,pid,rss --sort +rss
COMMAND            PID   RSS
stress            2795   424
stress            2797   428
stress            2798 65544
stress            2796 131212

5.3 PIDを昇順、降順に表示する方法

  • PIDを昇順に表示した場合
[root@server ~]# ps ax -o comm,pid --sort pid |head -n 5
COMMAND            PID
systemd              1
kthreadd             2
kworker/0:0H         4
ksoftirqd/0          6
  • PIDを降順に表示した場合
[root@server ~]# ps ax -o comm,pid --sort -pid |head -n 5
COMMAND            PID
head              2741
ps                2740
kworker/0:2       2724
kworker/0:0       2703

6 実行ユーザ名、実行グループ名を表示する方法

[root@server ~]# systemctl start httpd.service
[root@server ~]# ps -C httpd -o comm,pid,ppid,user,euser,group,egroup
COMMAND            PID   PPID USER     EUSER    GROUP    EGROUP
httpd             2759      1 root     root     root     root
httpd             2760   2759 apache   apache   apache   apache
httpd             2761   2759 apache   apache   apache   apache
httpd             2762   2759 apache   apache   apache   apache
httpd             2763   2759 apache   apache   apache   apache
httpd             2764   2759 apache   apache   apache   apache

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ