一 gdb 对于 父子进程的 调试
使用gdb调试的时候,gdb只能跟踪一个进程。可以在fork函数调用之前,通过指令设置gdb调试工具跟踪父进程或者是跟踪子进程。默认跟踪父进程。
set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程。
set follow-fork-mode parent 设置跟踪父进程。
注意,一定要在fork函数调用之前设置才有效。
另外,如果有多个子进程,没有办法设置跟踪哪一个子进程,
因此个人觉得 这个GDB 在多进程的代码中 好像作用不大
二 exec函数族原理分析
当在子进程 执行 exec函数后,那么子进程中就不会变成 exec函数中传递的是啥,就执行啥
fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
将当前进程的.text、.data替换为所要加载的程序的.text、.data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳。
其实有六种以exec开头的函数,统称exec函数:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
execlp函数 重点
加载一个进程,借助PATH环境变量
int execlp(const char *file, const char *arg, ...); 成功:无返回;失败:-1
参数1:要加载的程序的名字。该函数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没有参数1则出错返回。
该函数通常用来调用系统程序。如:ls、date、cp、cat等命令。
execl函数 重点
加载一个进程, 通过 路径+程序名 来加载。
int execl(const char *path, const char *arg, ...); 成功:无返回;失败:-1
对比execlp,如加载"ls"命令带有-l,-F参数
execlp("ls", "ls", "-l", "-F", NULL); 使用程序名在PATH中搜索。
execl("/bin/ls", "ls", "-l", "-F", NULL); 使用参数1给出的绝对路径搜索。
RETURN VALUE:成功时没有返回值,只有在返回-1的时候才会
The exec() functions return only if an error has occurred. The return
value is -1, and errno is set to indicate the error.
execvp函数
加载一个进程,使用自定义环境变量env
int execvp(const char *file, const char *argv[]);
变参形式: ①... ② argv[] (main函数也是变参函数,形式上等同于 int main(int argc, char *argv0, ...))
变参终止条件:① NULL结尾 ② 固参指定
execvp与execlp参数形式不同,原理一致。
练习:将当前系统中的进程信息,打印到文件中。 【exec_ps.c】
exec函数族一般规律
exec函数一旦调用成功即执行新的程序,不返回。只有失败才返回,错误值-1。所以通常我们直接在exec函数调用后直接调用perror()和exit(),无需if判断。
l (list) 命令行参数列表
p (path) 搜素file时使用path变量
v (vector) 使用命令行参数数组
e (environment) 使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量
事实上,只有execve是真正的系统调用,其它五个函数最终都调用execve,所以execve在man手册第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。
exec函数族
例子,使用execl 和 execlp在子进程中启动其他命令或者程序
注意的是: execl在执行的时候,第一个参数要包含你要运行的可执行程序的名字
execl("/home/hunandede/day02/dongtailib/a.out","a.out",NULL);
execlp 在执行的时候,第一个参数要包含你要运行的可执行程序的名字,第一个参数的意义是:要在环境变量 path下查找ls,第二个参数是执行的命令,第三个参数是命令参数.....最后一个参数是哨兵
execlp("ls","ls","-l",NULL);
int main() {
pid_t pid = fork();
if (pid == -1) {
perror("fork error");
exit(1);
}
else if (pid == 0) {
//子进程 execlp参数一表示从path环境变量中找 ls,第二个参数,才是要执行的命令,最后一个参数是 “哨兵位”
//execlp("ls","ls","-l",NULL);
execl("/home/hunandede/day02/dongtailib/a.out","a.out",NULL);
//execl中的命令,如果执行成功,则没有返回值,也就是说,如果能执行到这里,说明执行命令有error
perror("execl a.out error");
exit(1);
}
else if (pid>0) {
//父进程
sleep(1);
cout << "我是父进程" << endl;
}
cout << "理论上父子进程都要执行我" << endl;
return 0;
}
例子,将 ps aux 显示所有进程信息保存到psaux.txt文件中
//思路分析:
//1.肯定是要先有 psaux.txt这个文件,如果没有,则创建, 需要使用 open函数
//2.ps aux 的结果是输出到 屏幕上的。
//3.那么需要将 从屏幕上的结果 重定向到 psaux.txt中 ,需要使用dup2函数
//4.最后肯定要执行 ps aux
//将ps aux 的结果导入到 psaux.txt文件中
//思路分析:
//1.肯定是要先有 psaux.txt这个文件,如果没有,则创建, 需要使用 open函数
//2.ps aux 的结果是输出到 屏幕上的。
//3.那么需要将 从屏幕上的结果 重定向到 psaux.txt中 ,需要使用dup2函数
//4.最后肯定要执行 ps aux
int main() {
//int open(const char *pathname, int flags, mode_t mode);
int ret = 0;
int fd = 0;
fd = open("/home/hunandede/projects/linuxcpp/psaux.txt", O_RDWR|O_CREAT, 0664);
if (fd == -1) {
perror("open psaux.txt error");
ret = errno;
return ret;
}
ret = dup2(fd , STDOUT_FILENO);
if (ret == -1) {
perror("dup2 fd STDOUT_FILENO error");
ret = errno;
return ret;
}
cout << "fd =" << fd << " ret = " << ret << endl;
ret = execlp("ps","ps","aux",NULL);
if (ret == -1) {
perror("execlp(ps,ps,aux,NULL) error");
ret = errno;
return ret;
}
return ret;
}
三,孤儿进程 和 僵尸进程
孤儿进程
孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,这时候,由于父进程已经结束了,系统自带的init进程会变成这个子进程的父进程,init进程也称为 孤儿领养院。
【orphan.c】
僵尸进程
僵尸进程: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。
【zoom .c】
特别注意,僵尸进程是不能使用kill命令清除掉的。因为kill命令只是用来终止进程的,而僵尸进程已经终止。思考!用什么办法可清除掉僵尸进程呢?
wait函数:阻塞回收任意一个子线程
一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中用特殊变量$?查看,因为Shell是它的父进程,当它终止时Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。
父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:
① 阻塞等待子进程退出
② 回收子进程残留资源
③ 获取子进程结束状态(退出原因)。
pid_t wait(int *status); 成功:清理掉的子进程ID;失败:-1 (没有子进程)
当进程终止时,操作系统的隐式回收机制会:1.关闭所有文件描述符 2. 释放用户空间分配的内存。内核的PCB仍存在。其中保存该进程的退出状态。(正常终止→退出值;异常终止→终止信号)
可使用wait函数传出参数status来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组:
1. WIFEXITED(status) 为非0 → 进程正常结束
WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)
2. WIFSIGNALED(status) 为非0 → 进程异常终止
WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。
*3. WIFSTOPPED(status) 为非0 → 进程处于暂停状态
WSTOPSIG(status) 如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。
WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行
【wait1.c、wait2.c】
waitpid函数:阻塞或非阻塞回收子进程,可指定具体的子进程
作用同wait,但可指定pid进程清理,可以不阻塞。
pid_t waitpid(pid_t pid, int *status, in options); 成功:返回清理掉的子进程ID;失败:-1(无子进程)
参数pid:
> 0 回收指定ID的子进程
-1 回收任意子进程(相当于wait)
0 回收和当前调用waitpid一个组的所有子进程
< -1 回收指定进程组内的任意子进程, 第一个参数如果是-1002,表示要回收1002组的任意子进程
如果第三个参数为0。表示要阻塞等待子进程结束后回收
如果第三个参数为WNOHANG。意思是不阻塞,表示不需要等待子进程,如果这时候子进程还没有结束,则直接返回0
返回值
-1 表示error ,errno被设置
如果成功,则返回 child pid,是一个大于0的值
如果是0,表示不阻塞,且这时候子进程并没有执行完成,无法回收。
注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。 【waitpid.c】
作业:父进程fork 3 个子进程,三个子进程一个调用ps命令, 一个调用自定义程序1(正常),一个调用自定义程序2(会出段错误)。父进程使用waitpid对其子进程进行回收。
wait 函数例子:
pid_t wpid = waitpid(pid, &status, 0);//如果第三个参数为0。表示要子进程结束后回收
pid_t wpid = waitpid(pid, &status, WNOHANG);//回收指定ID的子进程 WNOHANG是立即返回,不阻塞的意思
pid_t wpid = waitpid(-1, &status, WNOHANG);//如果第一个参数是-1,回收任意一个子进程,相当于wait的作用
pid_t wpid = waitpid(0, &status, WNOHANG);//如果第一个参数是0,回收和主线程在同一组的任意一个子进程
pid_t wpid = waitpid(-2, &status, WNOHANG);//如果第一个参数是小于-1的,回收指定组的任意一个子进程
//wait 函数例子
int main() {
int ret = 0;
pid_t pid = fork();
int status = 0;
if (pid<0) {
//说明create子进程的时候出现错误
perror("fork() has been error");
ret = pid;
return ret;
}
if (pid==0) {
//子进程
cout << "我是子进程,我要睡10秒 getpid() = " << getpid() << " getppid()=" << getppid ()<< endl;
sleep(10);
cout << "我是子进程,我马上死亡" << endl;
}
else if (pid>0) {
//父进程
cout << "father 进程 wait之前的代码" << endl;
pid_t wpid = wait(&status);
if (wpid==-1) {
///wait失败
perror("wait pid error");
ret = wpid;
return ret;
}
cout << "father 进程 wait之后的代码 " << endl;
if (WIFEXITED(status)) {//WIFEXITED(status)为真,说明是子线程是正常结束的。。使用WEXITSTATUS(status) --- 获取进程退出状态 (exit的参数)
cout << "子进程是正常结束的 ,死亡原因是 :" << WEXITSTATUS(status) << endl;
}
if (WIFSIGNALED(status)) {//WIFSIGNALED(status)为真,说明子线程异常终止。。使用WTERMSIG(status) --- 取得使进程终止的那个信号的编号
cout << "子进程不是正常结束的 ,死亡的信号是 :" << WTERMSIG(status) << endl;
}
}
return ret;
}
hunandede@hunandede-virtual-machine:~/projects/linuxcpp$ ./main
father 进程 wait之前的代码
我是子进程,我要睡10秒 getpid() = 8325 getppid()=8324
我是子进程,我马上死亡
father 进程 wait之后的代码
子进程是正常结束的 ,死亡原因是 :0
hunandede@hunandede-virtual-machine:~/projects/linuxcpp$ ./main
father 进程 wait之前的代码
我是子进程,我要睡10秒 getpid() = 8329 getppid()=8328
father 进程 wait之后的代码
子进程不是正常结束的 ,死亡的信号是 :9
上述代码验证时,使用了 kill -9 8329让子进程死亡,
关于kill 命令的参数可以使用 ,关于kill 的记录,参考 下面的内容
waitpid例子1,回忆create 5个子进程的方法
循环创建5个进程,记住5个子进程的进程id,坑点记录
//循环创建5个子进程,记录子进程的pid,这里要注意的坑较多
坑点1。我们之所以记录子进程的pid,是因为在学习 waitpid函数后,
我们需要在父进程中使用waitpid来 销毁子进程,使用的函数是 pid_t waitpid(pid_t pid, int *status, int options);
由于使用waitpid要在父进程,那么在create 子进程的时候,也要在父进程记录 子进程的pid。
这是因为 父子进程在fork之后的一些数据,是读时共享,写时复制的,
而记录pid是一个写的过程,因此在父进程记录的,这个pid就会保留在父进程,最后在父进程用 ,就没有问题。
坑点2:
当i=0,在父进程记录的时候,由于会再循环fork,因此下一次(i=1)create的子线程就会保留父进程记录的pid
这就是我们在子进程打印也能看到pid的原因。
坑点3:
我们在循环内部,如果是子进程,就会break出去,这是因为fork函数有两个返回值,因此在循环结束后,要判断i的值,确定主进程走的这块还是子进程走的这块
int main() {
int ret = 0;
int i = 0;
pid_t pids[5] = { 0 };//初始化所有的 childpid,初始值都为0
for (; i < 5; i++) {
pid_t pid = fork();
if (pid==-1) {
perror("fork error ");
ret = pid;
return ret;
}
else if (pid ==0 ) {
//子进程,如果是子进程,不能参与下一次的 fork,只让主进程fork,因此在这里要break出去
//pids[i] = pid; //在这里写没有,只会在子进程中起作用
break;
}
else if (pid > 0 ) { //当pid >0的 时候,说明是父进程,那么要在父进程中记录 当前的pid
pids[i] = pid;//注意,这是在父进程中记录了所有的子进程的pid,那么在使用的时候,也只能在父进程使用,因为 读时共享写时复制.另外要注意的是,由于在循环中fork,上一次在父进程改动的pids[0]的值,在下一次fork时候,会带入
}
}
//因为 i = 0,1,2,3,4 的时候,这个i都是子进程break出来的,因此i在等于 0,1,2,3,4,时,都是子进程,只有i=5的时候,fork并没有执行,那么i=5的时候,就是父进程
if (i==5) {
cout << "我是父进程 getpid() = " << getpid() << " getppid()=" << getppid() << endl;
sleep(2);
//将记录的pids打印一下
for (int j = 0; j < 5; j++) {
cout << " fu pids[" << j << "] = " << pids[j];
}
cout << endl;
}
else {
cout << "我是子进程 getpid() = " << getpid() << " getppid()=" << getppid() << " i = " << i << endl;
//将记录的pids打印一下
for (int j = 0; j < 5; j++) {
cout << " zi pids[" << j << "] = " << pids[j];
}
cout << endl;
}
return ret;
}
我是子进程 getpid() = 12479 getppid()=12475 i = 0
zi pids[0] = 0 zi pids[1] = 0 zi pids[2] = 0 zi pids[3] = 0 zi pids[4] = 0
我是子进程 getpid() = 12480 getppid()=12475 i = 1
zi pids[0] = 12479 zi pids[1] = 0 zi pids[2] = 0 zi pids[3] = 0 zi pids[4] = 0
我是子进程 getpid() = 12481 getppid()=12475 i = 2
zi pids[0] = 12479 zi pids[1] = 12480 zi pids[2] = 0 zi pids[3] = 0 zi pids[4] = 0
我是子进程 getpid() = 12482 getppid()=12475 i = 3
zi pids[0] = 12479 zi pids[1] = 12480 zi pids[2] = 12481 zi pids[3] = 0 zi pids[4] = 0
我是子进程 getpid() = 12483 getppid()=12475 i = 4
zi pids[0] = 12479 zi pids[1] = 12480 zi pids[2] = 12481 zi pids[3] = 12482 zi pids[4] = 0
我是父进程 getpid() = 12475 getppid()=12473
fu pids[0] = 12479 fu pids[1] = 12480 fu pids[2] = 12481 fu pids[3] = 12482 fu pids[4] = 12483
waitpid例子2,使用waitpid,回收第三个子进程实例
int main() {
int ret = 0;
int i = 0;
pid_t pids[5] = { 0 };//初始化所有的 childpid,初始值都为0
for (; i < 5; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("fork error ");
ret = pid;
return ret;
}
else if (pid == 0) {
//子进程,如果是子进程,不能参与下一次的 fork,只让主进程fork,因此在这里要break出去
//pids[i] = pid; //在这里写没有,只会在子进程中起作用
break;
}
else if (pid > 0) { //当pid >0的 时候,说明是父进程,那么要在父进程中记录 当前的pid
pids[i] = pid;//注意,这是在父进程中记录了所有的子进程的pid,那么在使用的时候,也只能在父进程使用,因为 读时共享写时复制.另外要注意的是,由于在循环中fork,上一次在父进程改动的pids[0]的值,在下一次fork时候,会带入
}
}
//因为 i = 0,1,2,3,4 的时候,这个i都是子进程break出来的,因此i在等于 0,1,2,3,4,时,都是子进程,只有i=5的时候,fork并没有执行,那么i=5的时候,就是父进程
if (i == 5) {
cout << "我是父进程 getpid() = " << getpid() << " getppid()=" << getppid() << endl;
int status;
cout << "before waitpid pids[2] = " << pids[2] << endl;
pid_t wpid = waitpid(pids[2],&status,0);//阻塞等待第三个子进程结束,第三个参数是0,就是阻塞等待
if (wpid == -1) {
perror("waitpid pids[2] error");
ret = wpid;
return ret;
}
cout << "wpid = " << wpid << endl;
if (WIFEXITED(status)) {
cout << "正常结束 " << WEXITSTATUS(status) << endl;
}
if (WIFSIGNALED(status)) {
cout << "异常结束" << WTERMSIG(status) << endl;
}
}
return ret;
}
我是父进程 getpid() = 13879 getppid()=13877
before waitpid pids[2] = 13885
wpid = 13885
正常结束 0
使用阻塞方式和非阻塞方式回收多个子进程
//回收多个进程
int main() {
int ret = 0;
int i = 0;
pid_t pids[5] = { 0 };//初始化所有的 childpid,初始值都为0
for (; i < 5; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("fork error ");
ret = pid;
return ret;
}
else if (pid == 0) {
//子进程,如果是子进程,不能参与下一次的 fork,只让主进程fork,因此在这里要break出去
//pids[i] = pid; //在这里写没有,只会在子进程中起作用
break;
}
else if (pid > 0) { //当pid >0的 时候,说明是父进程,那么要在父进程中记录 当前的pid
pids[i] = pid;//注意,这是在父进程中记录了所有的子进程的pid,那么在使用的时候,也只能在父进程使用,因为 读时共享写时复制.另外要注意的是,由于在循环中fork,上一次在父进程改动的pids[0]的值,在下一次fork时候,会带入
}
}
//因为 i = 0,1,2,3,4 的时候,这个i都是子进程break出来的,因此i在等于 0,1,2,3,4,时,都是子进程,只有i=5的时候,fork并没有执行,那么i=5的时候,就是父进程
if (i == 5) {
cout << "我是父进程 getpid() = " << getpid() << " getppid()=" << getppid() << endl;
int status;
int wpid = 0;
//阻塞回收,阻塞回收的时候,阻塞回收失败的时候返回-1,成功返回wpid的值
//while ((wpid = waitpid(-1, &status, 0))) {
// if (wpid == -1) {
// perror("waitpid pids[2] error");
// ret = wpid;
// return ret;
// }
// cout << "wpid = " << wpid << endl;
// if (WIFEXITED(status)) {
// cout << "正常结束 " << WEXITSTATUS(status) << endl;
// }
// if (WIFSIGNALED(status)) {
// cout << "异常结束" << WTERMSIG(status) << endl;
// }
//}
//非阻塞回收,异常返回-1;正常回收,返回waitpid,;返回0,表示阻塞的进程还没有执行完
while ((wpid = waitpid(-1, &status, WNOHANG)) != -1) {
if (wpid>0) {
cout << "wpid = " << wpid << endl;
if (WIFEXITED(status)) {
cout << "正常结束 " << WEXITSTATUS(status) << endl;
}
if (WIFSIGNALED(status)) {
cout << "异常结束" << WTERMSIG(status) << endl;
}
}
else {
sleep(1);
}
}
}
return ret;
}
练习 作业:父进程fork 3 个子进程,三个子进程一个调用ps命令,
//一个调用自定义程序1(正常),
//一个调用自定义程序2(会出段错误)。
//父进程使用waitpid对其子进程进行回收。
//作业:父进程fork 3 个子进程,三个子进程一个调用ps命令,
//一个调用自定义程序1(正常),
//一个调用自定义程序2(会出段错误)。
//父进程使用waitpid对其子进程进行回收。
//设计思路:
//1.肯定先要fork 3 个子进程
//2.那么当这3个子进程fork出来,在哪里开始执行 3个程序呢?
//3.是不能再循环中执行的,这里要依赖于 i的值,这是因为在i= 0,1,2的时候,如果是子进程会break出去,也就是说跳出了循环
//4.那么我们在循环下面判断的时候,如果i=0的时候,就是子进程1
//在i=1的时候,就是子进程2
//在i=2的时候,就是子进程3
//在i=3的时候,就是父进程了,因此当i=3的时候,循环条件就不满足了,就不会进入到循环内部去fork,因此不会有子进程创建出来。
int main() {
int ret = 0;
int i = 0;
for (; i < 3;i++) {
pid_t pid = fork();
if (pid<0) {
perror("fork error");
ret = pid;
return ret;
}
if (pid==0) {
break;
}
}
if (i==0) {
//调用ps命令,execlp 成功没有返回值,失败返回-1
execlp("ps","ps","ajx",NULL);
perror("execlp ps error");
ret = errno;
return ret;
}
if (i==1) {
//一个调用自定义程序1(正常),
cout << "i=1" << endl;
execl("/home/hunandede/day02/dongtailib/a.out", "a.out", NULL);
perror("/home/hunandede/day02/dongtailib/a.out error");
ret = errno;
return ret;
}
if (i==2) {
//一个调用自定义程序2(会出段错误)。
cout << "i=2" << endl;
execl("/home/hunandede/day05/errorcode/makefilestudy7/a.out", "a.out", NULL);
perror("/home/hunandede/day02/dongtailib/a.out error");
ret = errno;
return ret;
}
if (i==3) {
//父进程 父进程使用waitpid对其子进程进行回收。
int status = 0;
int wpid = 0;
while ( ((wpid = waitpid(-1,&status, WNOHANG))!=-1 )) {
if (wpid>0) {
cout << "父进程回收成功,子进程pid = " <<wpid << endl;
if (WIFEXITED(status)) {//WIFEXITED(status)为真,说明是子线程是正常结束的。。使用WEXITSTATUS(status) --- 获取进程退出状态 (exit的参数)
cout << "子进程是正常结束的 ,死亡原因是 :" << WEXITSTATUS(status) << endl;
}
if (WIFSIGNALED(status)) {//WIFSIGNALED(status)为真,说明子线程异常终止。。使用WTERMSIG(status) --- 取得使进程终止的那个信号的编号
cout << "子进程不是正常结束的 ,死亡的信号是 :" << WTERMSIG(status) << endl;
}
}
else {
//就是阻塞情况下,子进程还没有运行完毕的case
sleep(1);
}
}
}
return ret;
}
i=1
i=2
a+b = 15
a-b = 5
a*b = 50
a+b = 20
a-b = 10
a*b = 75
a/b = 3
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 1 1 1 ? -1 Ss 0 0:03 /sbin/init splash
0 2 0 0 ? -1 S 0 0:00 [kthreadd]
2 4 0 0 ? -1 I< 0 0:00 [kworker/0:0H]
2 6 0 0 ? -1 I< 0 0:00 [mm_percpu_wq]
2 7 0 0 ? -1 S 0 0:00 [ksoftirqd/0]
2 8 0 0 ? -1 I 0 0:03 [rcu_sched]
2 9 0 0 ? -1 I 0 0:00 [rcu_bh]
2 10 0 0 ? -1 S 0 0:00 [migration/0]
2 11 0 0 ? -1 S 0 0:00 [watchdog/0]
2 12 0 0 ? -1 S 0 0:00 [cpuhp/0]
2 13 0 0 ? -1 S 0 0:00 [cpuhp/1]
2 14 0 0 ? -1 S 0 0:00 [watchdog/1]
2 15 0 0 ? -1 S 0 0:00 [migration/1]
2 16 0 0 ? -1 S 0 0:00 [ksoftirqd/1]
2 18 0 0 ? -1 I< 0 0:00 [kworker/1:0H]
2 19 0 0 ? -1 S 0 0:00 [cpuhp/2]
2 20 0 0 ? -1 S 0 0:00 [watchdog/2]
2 21 0 0 ? -1 S 0 0:00 [migration/2]
2 22 0 0 ? -1 S 0 0:00 [ksoftirqd/2]
2 24 0 0 ? -1 I< 0 0:00 [kworker/2:0H]
2 25 0 0 ? -1 S 0 0:00 [cpuhp/3]
2 26 0 0 ? -1 S 0 0:00 [watchdog/3]
2 27 0 0 ? -1 S 0 0:00 [migration/3]
2 28 0 0 ? -1 S 0 0:00 [ksoftirqd/3]
2 30 0 0 ? -1 I< 0 0:00 [kworker/3:0H]
2 31 0 0 ? -1 S 0 0:00 [kdevtmpfs]
2 32 0 0 ? -1 I< 0 0:00 [netns]
2 33 0 0 ? -1 S 0 0:00 [rcu_tasks_kthre]
2 34 0 0 ? -1 S 0 0:00 [kauditd]
2 37 0 0 ? -1 S 0 0:00 [khungtaskd]
2 38 0 0 ? -1 S 0 0:00 [oom_reaper]
2 39 0 0 ? -1 I< 0 0:00 [writeback]
2 40 0 0 ? -1 S 0 0:00 [kcompactd0]
2 41 0 0 ? -1 SN 0 0:00 [ksmd]
2 42 0 0 ? -1 SN 0 0:00 [khugepaged]
2 43 0 0 ? -1 I< 0 0:00 [crypto]
2 44 0 0 ? -1 I< 0 0:00 [kintegrityd]
2 45 0 0 ? -1 I< 0 0:00 [kblockd]
2 46 0 0 ? -1 I< 0 0:00 [ata_sff]
2 47 0 0 ? -1 I< 0 0:00 [md]
2 48 0 0 ? -1 I< 0 0:00 [edac-poller]
2 49 0 0 ? -1 I< 0 0:00 [devfreq_wq]
2 50 0 0 ? -1 I< 0 0:00 [watchdogd]
2 55 0 0 ? -1 S 0 0:00 [kswapd0]
2 56 0 0 ? -1 I< 0 0:00 [kworker/u257:0]
2 57 0 0 ? -1 S 0 0:00 [ecryptfs-kthrea]
2 99 0 0 ? -1 I< 0 0:00 [kthrotld]
2 100 0 0 ? -1 I< 0 0:00 [acpi_thermal_pm]
2 101 0 0 ? -1 S 0 0:00 [scsi_eh_0]
2 102 0 0 ? -1 I< 0 0:00 [scsi_tmf_0]
2 103 0 0 ? -1 S 0 0:00 [scsi_eh_1]
2 104 0 0 ? -1 I< 0 0:00 [scsi_tmf_1]
2 110 0 0 ? -1 I< 0 0:00 [ipv6_addrconf]
2 119 0 0 ? -1 I< 0 0:00 [kstrp]
2 136 0 0 ? -1 I< 0 0:00 [charger_manager]
2 186 0 0 ? -1 I< 0 0:00 [mpt_poll_0]
2 187 0 0 ? -1 I< 0 0:00 [mpt/0]
2 188 0 0 ? -1 S 0 0:00 [scsi_eh_2]
2 189 0 0 ? -1 I< 0 0:00 [scsi_tmf_2]
2 190 0 0 ? -1 S 0 0:00 [scsi_eh_3]
2 191 0 0 ? -1 I< 0 0:00 [scsi_tmf_3]
2 192 0 0 ? -1 S 0 0:00 [scsi_eh_4]
2 193 0 0 ? -1 I< 0 0:00 [scsi_tmf_4]
2 194 0 0 ? -1 S 0 0:00 [scsi_eh_5]
2 195 0 0 ? -1 I< 0 0:00 [scsi_tmf_5]
2 196 0 0 ? -1 S 0 0:00 [scsi_eh_6]
2 197 0 0 ? -1 I< 0 0:00 [scsi_tmf_6]
2 198 0 0 ? -1 S 0 0:00 [scsi_eh_7]
2 199 0 0 ? -1 I< 0 0:00 [scsi_tmf_7]
2 200 0 0 ? -1 S 0 0:00 [scsi_eh_8]
2 201 0 0 ? -1 I< 0 0:00 [scsi_tmf_8]
2 202 0 0 ? -1 S 0 0:00 [scsi_eh_9]
2 203 0 0 ? -1 I< 0 0:00 [scsi_tmf_9]
2 204 0 0 ? -1 S 0 0:00 [scsi_eh_10]
2 205 0 0 ? -1 I< 0 0:00 [scsi_tmf_10]
2 206 0 0 ? -1 S 0 0:00 [scsi_eh_11]
2 207 0 0 ? -1 I< 0 0:00 [scsi_tmf_11]
2 208 0 0 ? -1 S 0 0:00 [scsi_eh_12]
2 209 0 0 ? -1 I< 0 0:00 [scsi_tmf_12]
2 210 0 0 ? -1 S 0 0:00 [scsi_eh_13]
2 211 0 0 ? -1 I< 0 0:00 [scsi_tmf_13]
2 212 0 0 ? -1 S 0 0:00 [scsi_eh_14]
2 213 0 0 ? -1 I< 0 0:00 [scsi_tmf_14]
2 214 0 0 ? -1 S 0 0:00 [scsi_eh_15]
2 215 0 0 ? -1 I< 0 0:00 [scsi_tmf_15]
2 216 0 0 ? -1 S 0 0:00 [scsi_eh_16]
2 217 0 0 ? -1 I< 0 0:00 [scsi_tmf_16]
2 218 0 0 ? -1 S 0 0:00 [scsi_eh_17]
2 219 0 0 ? -1 I< 0 0:00 [scsi_tmf_17]
2 220 0 0 ? -1 S 0 0:00 [scsi_eh_18]
2 221 0 0 ? -1 I< 0 0:00 [scsi_tmf_18]
2 222 0 0 ? -1 S 0 0:00 [scsi_eh_19]
2 223 0 0 ? -1 I< 0 0:00 [scsi_tmf_19]
2 224 0 0 ? -1 S 0 0:00 [scsi_eh_20]
2 225 0 0 ? -1 I< 0 0:00 [scsi_tmf_20]
2 226 0 0 ? -1 S 0 0:00 [scsi_eh_21]
2 227 0 0 ? -1 I< 0 0:00 [scsi_tmf_21]
2 228 0 0 ? -1 S 0 0:00 [scsi_eh_22]
2 229 0 0 ? -1 I< 0 0:00 [scsi_tmf_22]
2 230 0 0 ? -1 S 0 0:00 [scsi_eh_23]
2 231 0 0 ? -1 I< 0 0:00 [scsi_tmf_23]
2 232 0 0 ? -1 S 0 0:00 [scsi_eh_24]
2 233 0 0 ? -1 I< 0 0:00 [scsi_tmf_24]
2 234 0 0 ? -1 S 0 0:00 [scsi_eh_25]
2 235 0 0 ? -1 I< 0 0:00 [scsi_tmf_25]
2 236 0 0 ? -1 S 0 0:00 [scsi_eh_26]
2 237 0 0 ? -1 I< 0 0:00 [scsi_tmf_26]
2 238 0 0 ? -1 S 0 0:00 [scsi_eh_27]
2 239 0 0 ? -1 I< 0 0:00 [scsi_tmf_27]
2 240 0 0 ? -1 S 0 0:00 [scsi_eh_28]
2 241 0 0 ? -1 I< 0 0:00 [scsi_tmf_28]
2 242 0 0 ? -1 S 0 0:00 [scsi_eh_29]
2 243 0 0 ? -1 I< 0 0:00 [scsi_tmf_29]
2 244 0 0 ? -1 S 0 0:00 [scsi_eh_30]
2 245 0 0 ? -1 I< 0 0:00 [scsi_tmf_30]
2 246 0 0 ? -1 S 0 0:00 [scsi_eh_31]
2 247 0 0 ? -1 I< 0 0:00 [scsi_tmf_31]
2 248 0 0 ? -1 S 0 0:00 [scsi_eh_32]
2 249 0 0 ? -1 I< 0 0:00 [scsi_tmf_32]
2 277 0 0 ? -1 I< 0 0:00 [ttm_swap]
2 278 0 0 ? -1 S 0 0:00 [irq/16-vmwgfx]
2 281 0 0 ? -1 I< 0 0:00 [kworker/3:1H]
2 282 0 0 ? -1 I< 0 0:00 [kworker/2:1H]
2 294 0 0 ? -1 I< 0 0:00 [kworker/0:1H]
2 307 0 0 ? -1 S 0 0:00 [jbd2/sda1-8]
2 308 0 0 ? -1 I< 0 0:00 [ext4-rsv-conver]
2 335 0 0 ? -1 I< 0 0:00 [kworker/1:1H]
1 340 340 340 ? -1 Ss 0 0:00 /lib/systemd/systemd-journald
1 381 381 381 ? -1 Ss 0 0:00 /lib/systemd/systemd-udevd
1 426 426 426 ? -1 Ssl 100 0:00 /lib/systemd/systemd-timesyncd
1 828 828 828 ? -1 Ssl 0 0:12 /usr/lib/accountsservice/accounts-daemon
1 832 832 832 ? -1 Ss 111 0:01 avahi-daemon: running [hunandede-virtual-machine.local]
1 836 836 836 ? -1 Ss 0 0:00 /lib/systemd/systemd-logind
1 840 840 840 ? -1 Ss 106 0:06 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile -
832 845 832 832 ? -1 S 111 0:00 avahi-daemon: chroot helper
1 896 896 896 ? -1 Ssl 0 0:02 /usr/sbin/NetworkManager --no-daemon
1 906 906 906 ? -1 Ss 0 0:00 /usr/sbin/cron -f
1 920 920 920 ? -1 Ss 0 0:00 /usr/sbin/acpid
1 922 922 922 ? -1 Ssl 104 0:00 /usr/sbin/rsyslogd -n
1 950 950 950 ? -1 Ss 0 0:02 /usr/sbin/irqbalance --pid=/var/run/irqbalance.pid
1 951 951 951 ? -1 SLsl 0 0:01 /usr/sbin/lightdm
951 984 984 984 tty7 984 Ssl+ 0 0:33 /usr/lib/xorg/Xorg -core :0 -seat seat0 -auth /var/run/lightdm/root/:0
1 1079 1079 1079 ? -1 Ssl 0 0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shut
1 1092 1092 1092 ? -1 Ss 0 0:00 /usr/sbin/sshd -D
1 1098 1098 1098 ? -1 Ssl 0 0:05 /usr/lib/policykit-1/polkitd --no-debug
1 1230 1230 1230 ? -1 Ssl 0 0:00 /usr/bin/vmhgfs-fuse -o subtype=vmhgfs-fuse,allow_other /mnt/hgfs
1 1258 1258 1258 ? -1 Ssl 0 0:00 /usr/sbin/vmware-vmblock-fuse -o subtype=vmware-vmblock,default_permiss
1 1297 1296 1296 ? -1 Sl 0 0:45 /usr/sbin/vmtoolsd
1 1339 1338 1338 ? -1 S 0 0:00 /usr/lib/vmware-vgauth/VGAuthService -s
1 1349 1349 1349 ? -1 Ssl 109 0:00 /usr/bin/whoopsie -f
1 1358 1358 1358 tty1 1358 Ss+ 0 0:00 /sbin/agetty --noclear tty1 linux
951 1385 951 951 ? -1 Sl 0 0:00 lightdm --session-child 12 19
1 1484 1484 1484 ? -1 SNsl 118 0:00 /usr/lib/rtkit/rtkit-daemon
1 1512 1512 1512 ? -1 Ssl 0 0:00 /usr/lib/upower/upowerd
1 1580 1580 1580 ? -1 Ssl 113 0:00 /usr/lib/colord/colord
1092 2091 2091 2091 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1 2093 2093 2093 ? -1 Ss 1000 0:00 /lib/systemd/systemd --user
2093 2094 2093 2093 ? -1 S 1000 0:00 (sd-pam)
1092 2107 2107 2107 ? -1 Ss 0 0:00 sshd: hunandede [priv]
2091 2150 2091 2091 ? -1 S 1000 0:00 sshd: hunandede@notty
2107 2178 2107 2107 ? -1 S 1000 0:00 sshd: hunandede@notty
2178 2179 2179 2179 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1 2569 2569 2569 ? -1 Ss 0 0:00 /usr/sbin/cupsd -l
1 2570 2570 2570 ? -1 Ssl 0 0:00 /usr/sbin/cups-browsed
1 2641 2640 2640 ? -1 Sl 1000 0:00 /usr/bin/gnome-keyring-daemon --daemonize --login
1385 2644 2644 2644 ? -1 Ss 1000 0:00 /sbin/upstart --user
2644 2721 2720 2720 ? -1 S 1000 0:00 upstart-udev-bridge --daemon --user
2644 2722 2722 2722 ? -1 Rs 1000 0:02 dbus-daemon --fork --session --address=unix:abstract=/tmp/dbus-3DvczvfW
2644 2734 2734 2734 ? -1 Ss 1000 0:00 /usr/lib/x86_64-linux-gnu/hud/window-stack-bridge
2644 2760 2759 2759 ? -1 S 1000 0:00 upstart-dbus-bridge --daemon --system --user --bus-name system
2644 2762 2761 2761 ? -1 S 1000 0:00 upstart-file-bridge --daemon --user
2644 2764 2763 2763 ? -1 S 1000 0:00 upstart-dbus-bridge --daemon --session --user --bus-name session
2644 2768 2767 2767 ? -1 Sl 1000 0:01 /usr/bin/fcitx
2644 2789 2789 2789 ? -1 Ssl 1000 0:01 /usr/lib/x86_64-linux-gnu/bamf/bamfdaemon
2644 2790 2790 2790 ? -1 Ss 1000 0:00 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --config-fi
2644 2798 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd
2644 2803 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd-fuse /run/user/1000/gvfs -f -o big_writes
2644 2820 2819 2819 ? -1 SN 1000 0:00 /usr/bin/fcitx-dbus-watcher unix:abstract=/tmp/dbus-8TfGJ2G6rS,guid=d0b
2644 2824 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/x86_64-linux-gnu/notify-osd
2644 2830 2830 2830 ? -1 Ss 1000 0:01 gpg-agent --homedir /home/hunandede/.gnupg --use-standard-socket --daem
2644 2845 2845 2845 ? -1 Ssl 1000 0:02 /usr/lib/x86_64-linux-gnu/hud/hud-service
2644 2847 2847 2847 ? -1 Ssl 1000 0:07 /usr/lib/unity-settings-daemon/unity-settings-daemon
2644 2855 2855 2855 ? -1 Ssl 1000 0:00 /usr/lib/at-spi2-core/at-spi-bus-launcher --launch-immediately
2644 2857 2857 2857 ? -1 Ssl 1000 0:00 /usr/lib/gnome-session/gnome-session-binary --session=ubuntu
2644 2868 2868 2868 ? -1 Ssl 1000 0:03 /usr/lib/x86_64-linux-gnu/unity/unity-panel-service
2855 2872 2855 2855 ? -1 S 1000 0:00 /usr/bin/dbus-daemon --config-file=/etc/at-spi2/accessibility.conf --no
2644 2887 2855 2855 ? -1 Sl 1000 0:00 /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
2644 2909 2909 2909 ? -1 Ssl 1000 0:06 /usr/lib/x86_64-linux-gnu/indicator-messages/indicator-messages-service
2644 2914 2914 2914 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-bluetooth/indicator-bluetooth-servi
2644 2916 2916 2916 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-power/indicator-power-service
2644 2919 2919 2919 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-datetime/indicator-datetime-service
2644 2921 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/dconf/dconf-service
2644 2924 2924 2924 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-keyboard/indicator-keyboard-service
2644 2928 2928 2928 ? -1 Ssl 1000 0:08 /usr/lib/x86_64-linux-gnu/indicator-sound/indicator-sound-service
2644 2930 2930 2930 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-printers/indicator-printers-service
2644 2932 2932 2932 ? -1 Ssl 1000 0:02 /usr/lib/x86_64-linux-gnu/indicator-session/indicator-session-service
2644 2937 2937 2937 ? -1 Ssl 1000 0:00 /usr/lib/x86_64-linux-gnu/indicator-application/indicator-application-s
2644 2969 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-source-registry
2644 2978 2977 2977 ? -1 S<l 1000 0:00 /usr/bin/pulseaudio --start --log-target=syslog
2644 3001 3001 3001 ? -1 Ssl 1000 0:47 compiz
2857 3027 2857 2857 ? -1 SLl 1000 0:02 /usr/bin/gnome-software --gapplication-service
2644 3030 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-calendar-factory
2857 3032 2857 2857 ? -1 Sl 1000 0:08 nautilus -n
2857 3033 2857 2857 ? -1 Sl 1000 0:00 /usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1
2857 3035 2857 2857 ? -1 Sl 1000 0:00 /usr/lib/unity-settings-daemon/unity-fallback-mount-helper
2857 3039 2857 2857 ? -1 Sl 1000 0:00 nm-applet
2644 3044 2857 2857 ? -1 Sl 1000 0:51 /usr/lib/vmware-tools/sbin64/vmtoolsd -n vmusr --blockFd 3
2644 3083 2722 2722 ? -1 S 1000 0:00 /usr/lib/x86_64-linux-gnu/gconf/gconfd-2
2644 3088 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfs-udisks2-volume-monitor
1 3096 3096 3096 ? -1 Ssl 0 0:00 /usr/lib/udisks2/udisksd --no-debug
1 3122 3122 3122 ? -1 Ssl 0 0:01 /usr/lib/x86_64-linux-gnu/fwupd/fwupd
3030 3133 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-calendar-factory-subprocess --factory cont
2644 3137 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfs-goa-volume-monitor
2644 3142 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfs-afc-volume-monitor
2644 3154 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfs-mtp-volume-monitor
2644 3159 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
2644 3184 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-addressbook-factory
3030 3186 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-calendar-factory-subprocess --factory loca
2644 3199 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd-trash --spawner :1.6 /org/gtk/gvfs/exec_spaw/0
3184 3202 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/evolution/evolution-addressbook-factory-subprocess --factory l
2644 3237 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd-metadata
2644 3249 3248 3248 ? -1 Sl 1000 0:01 fcitx-qimpanel
2644 3280 2722 2722 ? -1 Rl 1000 0:14 /usr/lib/gnome-terminal/gnome-terminal-server
2644 3303 2722 2722 ? -1 S 1000 0:00 /bin/sh -c /usr/lib/x86_64-linux-gnu/zeitgeist/zeitgeist-maybe-vacuum;
3303 3307 2722 2722 ? -1 Sl 1000 0:00 /usr/bin/zeitgeist-daemon
2644 3314 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/x86_64-linux-gnu/zeitgeist-fts
2644 3318 2722 2722 ? -1 Sl 1000 0:00 zeitgeist-datahub
2857 3384 2857 2857 ? -1 Sl 1000 0:01 update-notifier
2857 3403 2857 2857 ? -1 Sl 1000 0:00 /usr/lib/x86_64-linux-gnu/deja-dup/deja-dup-monitor
1092 3495 3495 3495 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 3512 3512 3512 ? -1 Ss 0 0:00 sshd: hunandede [priv]
3495 3552 3495 3495 ? -1 S 1000 0:00 sshd: hunandede@notty
3512 3580 3512 3512 ? -1 S 1000 0:00 sshd: hunandede@notty
3580 3581 3581 3581 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2644 4193 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd-network --spawner :1.6 /org/gtk/gvfs/exec_spaw/1
2644 4224 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/gvfs/gvfsd-dnssd --spawner :1.6 /org/gtk/gvfs/exec_spaw/5
3280 4242 4242 4242 pts/4 4242 Ss+ 1000 0:00 bash
3280 4612 4612 4612 pts/20 16642 Ss 1000 0:00 bash
1092 4855 4855 4855 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 4872 4872 4872 ? -1 Ss 0 0:00 sshd: hunandede [priv]
4855 4910 4855 4855 ? -1 S 1000 0:00 sshd: hunandede@notty
4872 4938 4872 4872 ? -1 S 1000 0:00 sshd: hunandede@notty
4938 4939 4939 4939 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2644 5752 2857 2857 ? -1 Sl 1000 0:02 gedit /home/hunandede/projects/linuxcpp/psaux.txt
1092 6030 6030 6030 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 6047 6047 6047 ? -1 Ss 0 0:00 sshd: hunandede [priv]
6030 6086 6030 6030 ? -1 S 1000 0:00 sshd: hunandede@notty
6047 6117 6047 6047 ? -1 S 1000 0:00 sshd: hunandede@notty
6117 6118 6118 6118 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1092 6543 6543 6543 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 6560 6560 6560 ? -1 Ss 0 0:00 sshd: hunandede [priv]
6543 6597 6543 6543 ? -1 S 1000 0:00 sshd: hunandede@notty
6560 6625 6560 6560 ? -1 S 1000 0:00 sshd: hunandede@notty
6625 6626 6626 6626 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2644 6974 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/x86_64-linux-gnu/unity-scope-home/unity-scope-home
2644 6985 2722 2722 ? -1 Sl 1000 0:01 /usr/bin/unity-scope-loader applications/applications.scope application
2644 6987 2722 2722 ? -1 Sl 1000 0:00 /usr/lib/x86_64-linux-gnu/unity-lens-files/unity-files-daemon
1092 7132 7132 7132 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 7149 7149 7149 ? -1 Ss 0 0:00 sshd: hunandede [priv]
7132 7186 7132 7132 ? -1 S 1000 0:00 sshd: hunandede@notty
7149 7214 7149 7149 ? -1 S 1000 0:00 sshd: hunandede@notty
7214 7215 7215 7215 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1092 7644 7644 7644 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 7661 7661 7661 ? -1 Ss 0 0:00 sshd: hunandede [priv]
7644 7700 7644 7644 ? -1 S 1000 0:00 sshd: hunandede@notty
7661 7728 7661 7661 ? -1 S 1000 0:00 sshd: hunandede@notty
7728 7729 7729 7729 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
3280 8156 8156 8156 pts/11 8803 Ss 1000 0:00 bash
1092 8519 8519 8519 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 8536 8536 8536 ? -1 Ss 0 0:00 sshd: hunandede [priv]
8519 8574 8519 8519 ? -1 S 1000 0:00 sshd: hunandede@notty
8536 8602 8536 8536 ? -1 S 1000 0:00 sshd: hunandede@notty
8602 8603 8603 8603 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
8156 8803 8803 8156 pts/11 8803 S+ 1000 0:00 man 2 waitpid
8803 8815 8803 8156 pts/11 8803 S+ 1000 0:00 pager
1092 9089 9089 9089 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 9106 9106 9106 ? -1 Ss 0 0:00 sshd: hunandede [priv]
9089 9145 9089 9089 ? -1 S 1000 0:00 sshd: hunandede@notty
9106 9173 9106 9106 ? -1 S 1000 0:00 sshd: hunandede@notty
9173 9174 9174 9174 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1092 11733 11733 11733 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 11735 11735 11735 ? -1 Ss 0 0:00 sshd: hunandede [priv]
11733 11787 11733 11733 ? -1 S 1000 0:00 sshd: hunandede@notty
11735 11815 11735 11735 ? -1 S 1000 0:00 sshd: hunandede@notty
11815 11816 11816 11816 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1092 12624 12624 12624 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 12626 12626 12626 ? -1 Ss 0 0:00 sshd: hunandede [priv]
12624 12678 12624 12624 ? -1 S 1000 0:00 sshd: hunandede@notty
12626 12706 12626 12626 ? -1 S 1000 0:00 sshd: hunandede@notty
12706 12707 12707 12707 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
1092 13938 13938 13938 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 13940 13940 13940 ? -1 Ss 0 0:00 sshd: hunandede [priv]
13938 13969 13938 13938 ? -1 S 1000 0:00 sshd: hunandede@notty
13940 13997 13940 13940 ? -1 S 1000 0:00 sshd: hunandede@notty
13997 13998 13998 13998 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2 14825 0 0 ? -1 R 0 0:00 [kworker/u256:1]
2 15114 0 0 ? -1 I 0 0:02 [kworker/0:2]
1092 15327 15327 15327 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 15329 15329 15329 ? -1 Ss 0 0:00 sshd: hunandede [priv]
15327 15358 15327 15327 ? -1 S 1000 0:00 sshd: hunandede@notty
15329 15386 15329 15329 ? -1 S 1000 0:00 sshd: hunandede@notty
15386 15387 15387 15387 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2 15691 0 0 ? -1 I 0 0:00 [kworker/3:1]
2 15709 0 0 ? -1 I 0 0:00 [kworker/u256:2]
2 15805 0 0 ? -1 I 0 0:00 [kworker/u256:0]
2 15814 0 0 ? -1 I 0 0:00 [kworker/2:1]
1092 15941 15941 15941 ? -1 Ss 0 0:00 sshd: hunandede [priv]
1092 15958 15958 15958 ? -1 Ss 0 0:00 sshd: hunandede [priv]
15941 15972 15941 15941 ? -1 S 1000 0:00 sshd: hunandede@notty
15958 16000 15958 15958 ? -1 S 1000 0:00 sshd: hunandede@notty
16000 16001 16001 16001 ? -1 Ss 1000 0:00 /usr/lib/openssh/sftp-server
2 16128 0 0 ? -1 I 0 0:00 [kworker/2:3]
2 16187 0 0 ? -1 I 0 0:00 [kworker/0:3]
2 16318 0 0 ? -1 I 0 0:00 [kworker/1:0]
2 16319 0 0 ? -1 I 0 0:00 [kworker/1:3]
2 16376 0 0 ? -1 I 0 0:00 [kworker/3:2]
2 16434 0 0 ? -1 I 0 0:00 [kworker/u256:3]
2 16563 0 0 ? -1 I 0 0:00 [kworker/2:0]
2 16565 0 0 ? -1 I 0 0:00 [kworker/0:0]
2 16566 0 0 ? -1 I 0 0:00 [kworker/0:1]
2 16622 0 0 ? -1 I 0 0:00 [kworker/3:0]
2 16625 0 0 ? -1 I 0 0:00 [kworker/2:2]
4612 16642 16642 4612 pts/20 16642 S+ 1000 0:00 ./main
16642 16643 16642 4612 pts/20 16642 R+ 1000 0:00 ps ajx
16642 16644 16642 4612 pts/20 16642 Z+ 1000 0:00 [a.out] <defunct>
16642 16645 16642 4612 pts/20 16642 S+ 1000 0:00 a.out
2 16646 0 0 ? -1 R 0 0:00 /usr/bin/python3 /usr/share/apport/apport 16645 8 0 1 16645 !home!hunan
父进程回收成功,子进程pid = 16643
子进程是正常结束的 ,死亡原因是 :0
父进程回收成功,子进程pid = 16644
子进程是正常结束的 ,死亡原因是 :0
父进程回收成功,子进程pid = 16645
子进程不是正常结束的 ,死亡的信号是 :8
四 kill 命令 kill -l 查看可以让其死亡的参数有哪些
hunandede@hunandede-virtual-machine:~/day02/dongtailib$ 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