嵌入式学习之linux系统编程---15 进程控制(ps、kill、孤儿进程、僵尸进程、wait命令)

1、ps和kill命令

ps和kill命令的格式
ps命令:
ps命令可以列出系统中当前运行的那些进程
命令格式:ps[参数]
命令功能:用来显示当前进程的状态
常用参数:aux
kill命令
kill命令用来杀死进程
eg: kill -9(SIGKILL) PID号
9号代表的是SIGKILL信号

2、关于ps命令

在ubuntu界面输入“ps a”,可以得到一下信息。“a”参数代表的是显示一个终端上的所有进程。

root@ubuntu:/home/topeet# cd
root@ubuntu:~# cd /home/samba/practice/
root@ubuntu:/home/samba/practice# ls
a.c  a.out  b.c  c.c  open.c  practice2  practice2.c  test
root@ubuntu:/home/samba/practice# ps a
   PID TTY      STAT   TIME COMMAND
  1010 tty7     Ssl+   0:01 /usr/lib/xorg/Xorg -core :0 -seat seat0 -auth /var/r
  1538 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
  2717 pts/18   Ss     0:00 bash
  2798 pts/18   S      0:00 su root
  2829 pts/18   S      0:00 bash
  2877 pts/18   R+     0:00 ps a
TTY当前的进程是要关联终端的,可以与我们进行交互
STAT表示的是进程的状态,其中“z+”表示的是僵尸的
TIME表示进程的启动时间
COMMAND表示进程执行的具体的程序

注:< defunct >表示的是死掉了

“u”参数可以显示进程的归属用户以及相关的内存使用情况
在这里插入图片描述

VSZ表示进程使用的虚拟内存的大小
RSS表示进程使用的虚拟内存的大小
%cpu表示进程占用了cpu计算能力的百分比
%MEM占用内存的百分比

“x”参数表示当前的进程是不关联终端的
在这里插入图片描述
如果要查看一个进程的相关信息,可以在ubuntu终端使用“ps aux”命令,但是这个命令执行之后显示的信息太多啦,如何快速找到想要找的进程呢?可以用“管道”来找。比如:要找到aux这个进程的相关信息,在终端键入该命令即可:
“|”表示的是管道的意思

root@ubuntu:/home/samba/practice# ps aux | grep aux
root       3614  0.0  0.0  39104  3248 pts/18   R+   20:01   0:00 ps aux
root       3615  0.0  0.0  15984   944 pts/18   S+   20:01   0:00 grep --color=auto aux

3、关于kill命令

使用“kill -l”查看ubuntu中kill命令都有哪些信号,可以看到9号为SIGKILL,故使用kill命令时,可以使用 “kill -9 PID号”来结束进程。

root@ubuntu:/home/samba/practice# kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

在终端上执行可执行文件practice,再打开一个新的终端,查看practice的pid号,在新的终端上执行kill命令,原来的终端上会显示“已杀死”
在这里插入图片描述在这里插入图片描述在这里插入图片描述

4、孤儿进程、僵尸进程

孤儿进程 — 父进程结束以后,子进程还未结束,这个子进程就叫做孤儿进程。但是孤儿进程会被系统的init(pid号为1)进程所领养,此时它的父进程就变为了init进程。
僵尸进程 — 子进程结束以后,父进程还在运行,但是父进程不去释放进程控制块,这个子进程就叫做僵尸进程。
(1)关于孤儿进程的示例:
c代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
        int i=0;
        pid_t pid;
        // 创建一个子进程
        pid = fork();
        if (pid < 0)
        {
                printf("fork is error \n");
                return -1;
        }
        //父进程 让父进程先结束,并打印进程 PID
        if (pid > 0)
        {
                printf("pid is %d\n", getpid());
        }
        //子进程,让子进程等待一会,让父进程先结束,并打印子进程的父进程的 pid
        if (pid == 0)
        {
                sleep(2);
                printf("parent pid is %d\n", getppid());
        }
        return 0;
}

在ubuntu上的编译结果如下所示:
在这里插入图片描述
由该编译结果可以看出,子进程中打印的父进程的进程号和父进程的进程号是不一样的,说明创建的子进程变成了孤儿进程,此进程被系统的 init 进程"领养"了。
重新打开一个终端查看一下这个pid号为1825的进程是谁?可以看到1825是upstart这样的一个进程 因为我们在这里使用的是一个带图形界面的ubuntu界面的图形系统 ubuntu系统使用默认的upstart作为默认的“领养”进程
在这里插入图片描述
(2)关于僵尸进程的示例
僵尸进程(子进程结束以后 还有一部分的资源需要释放 而这些资源必须要由父进程去释放)
c代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
        int i=0;
        pid_t pid;
        // 创建一个子进程
        pid = fork();
        if (pid < 0)
        {
                printf("fork is error \n");
        return -1;
        }
        //父进程 
        //让父进程先结束,并打印进程 PID
        if (pid > 0)
        {
                while(1);
        }
        //子进程,让子进程先结束
        if (pid == 0)
        {
                printf("This is child\n");
                 exit(0);
        }
        return 0;
}

在ubuntu上的编译结果如下所示:
在这里插入图片描述
重新打开一个新的进程,查看该可执行文件“practice”的状态,如下图所示:
在这里插入图片描述

5、wait()函数

(1)wait()函数是一个阻塞函数,它调用函数,只能回收一个进程。
Wait是阻塞函数,它会一直阻塞在那里直到子进程退出,wait函数会自动分析当前进程的某个子进程是否已经退出,如果有退出的子进程 wait函数就会自动收集子进程的信息,然后将其彻底销毁,这样就可以减少僵尸进程的产生。

头文件:#include <sys/wait.h>
函数原型:pid_t wait(int *status)
返回值:执行成功,则返回回收的子进程的pid,失败则返回-1

(2)与 wait 函数的参数有关的俩个宏定义:

WIFEXITED(status):如果子进程正常退出,则该宏定义为真
WEXITSTATUS(status):如果子进程正常退出,则该宏定义的值为子进程的退出值。

(3)wait函数示例
c代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
        pid_t pid;
        //用fork函数创建一个子进程
        pid = fork();
        //创建失败
        if(pid < 0){
                printf("error\n");
        }
        //父进程,让父进程一直运行,没有时间去释放进程控制块
        if(pid > 0){
                int status;
                wait(&status);
        if(WIFEXITED(status)==1){
                printf("return value is %d\n",WEXITSTATUS(status));
        }
        //while(1); //这句如果取消注释,就会变成僵尸进程
        }
        //子进程,让子进程先结束
        if(pid == 0){
                sleep(2);
                printf("This is child\n");
                exit(0);
        }
        return 0;
}


在ubuntu终端编译的结果如下图所示:
在这里插入图片描述
最后打印的宏定义的值是子进程中的exit()函数中的值,此处是0,故打印值为0。若改为6 则打印值为6
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值