1. 进程查看
(1)ps命令:通常可以查看到:进程ID、进程的用户ID、进程状态和进程的COMMAND
①#ps aux //使用Unix操作系统的BSD格式,其中a表示所有前台,x表示后台进程,u表示显示创建进程的用户。
②#ps -lef //使用linux标准命令格式,其中l表示详细信息,e表示所有进程,f:full。
(2)ps输出信息
①USER:该进程是由哪个用户产生的。
②PID:进程的ID号。PPID:父进程
③%CPU:该进程占用CPU资源的百分比,占用越高,进程越耗费资源
④&MEM:该进程占用物理内存的百分比,占用越高,进程越耗费资源
⑤VSZ:该进程占用虚拟内存的大小,单位KB
⑥RSS:该进程占用实际物理内存的大小,单位KB
⑦TTY:该进程是在哪个终端运行的。其中的tty1-tty7代表本地控制台终端,tty1-tty67是本地的字符界面终端,tty7是图形终端。pts/0-255代表虚拟终端。
⑧STAT:进程状态。常见的状态有:R—运行;S-睡眠;T—停止状态;s-包含子进程;+—位于后台。
⑨START,TIME:进程启动时间和占用CPU的运算时间。
⑩COMMAND:产生此进程的命令名。
2. 进程状态
(1)进程的几种状态
常见状态 |
说明 |
运行状态 |
①系统当前进程;②就绪状态进程;③ps命令中STAT列为R值 |
等待状态 |
①等待事件发生;②等待系统资源;③ps命令中STAT列为S或D值。其中S表示可中断等待。D表示不可中断等待。 |
停止状态 |
①PS命令的STAT列为T值 |
僵尸状态 |
①进程终止或结束;②在进程表项中仍有记录;③ps命令的STAT列为Z值 |
(2)进程的状态变化
①TASK_RUNNING:进程正在被CPU执行。当一个进程刚被创建时会处于TASK_RUNNABLE,表示己经准备就绪,正等待被调度。
②TASK_INTERRUPTIBLE(可中断):进程正在睡眠(也就是说它被阻塞)等待某些条件的达成。一旦这些条件达成,内核就会把进程状态设置为运行。处于此状态的进程也会因为接收到信号而提前被唤醒,比如给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNABLE状态),然后再响应SIGKILL信号而退出(变为TASK_ZOMBIE状态),并不会从TASK_INTERRUPTIBLE状态直接退出。
③TASK_UNINTERRUPTIBLE(不可中断):处于等待中的进程,待资源满足时被唤醒,但不可以由其它进程通过信号或中断唤醒。由于不接受外来的任何信号,因此无法用kill杀掉这些处于该状态的进程。而TASK_UNINTERRUPTIBLE状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程,于是原有的流程就被中断了,这可能使某些设备陷入不可控的状态。处于TASK_UNINTERRUPTIBLE状态一般总是非常短暂的,通过ps命令基本上不可能捕捉到。
④TASK_ZOMBIE(僵死):表示进程已经结束了,但是其父进程还没有调用wait4或waitpid()来释放进程描述符。为了父进程能够获知它的消息,子进程的进程描述符仍然被保留着。一旦父进程调用了wait4(),进程描述符就会被释放。
⑤TASK_STOPPED(停止):进程停止执行。当进程接收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。当接收到SIGCONT信号,会重新回到TASK_RUNNABLE。
3. 进程标识及相关函数
头文件 |
#include<unistd.h> #include<sys/types.h> |
函数 |
①pid_t getpid(void); //获得当前进程ID ②uid_t getuid(void); //获得当前进程的实际用户ID ③uid_t geteuid(void); //获得当前进程的有效用户ID ④gid_t getgid(void); //获得当前进程的用户组ID ⑤pid_t getppid(void); //获得当前进程的父进程ID ⑥pid_t getpgrp(void); //获得当前进程所在的进程组ID ⑦pid_t getpgid(pid_t pid);//获得指定进程所在的进程组ID |
【编程实验】查看进程标识
//process_id.c
#include <unistd.h> #include <stdio.h> int main(int argc, char* argv[]) { printf("pid: %d ", getpid()); //进程ID printf("ppid: %d ", getppid()); //父进程ID printf("uid: %d ", getuid()); printf("euid: %d ", geteuid()); printf("user gid: %d ", getgid()); //用户组ID printf("gid: %d ", getpgrp()); //进程组ID printf("pgid: %d ", getpgid(getpid())); //当前进程的进程组ID printf("ppid: %d ", getpgid(getppid())); //父进程的进程组ID return 0; }