赞
踩
O:就绪态,一切准备工作都已经做好,等待被调用。
R:运行态,Linux下没有就绪态,O也就是R。
S:可唤醒的睡眠态,系统调用、获取到资源、收到信息都可以被唤醒。
D:不可唤醒的睡眠态,必须等到的事件发生。
T:暂停态,收到了SIGSTOP信号,当收到SIGCONT信号则继续运行。
X:死亡态。
Z:僵尸态。
<:高优先级。
N:低优先级。
L:多线程进程。
s:有子进程的进程。
+:后台进程组。
ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 126212 4296 ? Ss Sep14 0:19 /usr/lib/systemd/systemd --switched
root 2 0.0 0.0 0 0 ? S Sep14 0:00 [kthreadd]
可以通过ps的命令来看到进程的状态:STAT
一个进程可以拥有多种状态。
pid_t fork(void);
功能:创建子进程
1、失败返回-1,如果成功会返回两次。
2、父进程会返回子进程的id,子进程返回0
3、根据返回值的不同,分别为子进程和父进程设计不同的分支。
4、通过fork创建出的子进程,就是父进程的副本,它会把父进程的堆、栈、全局段、静态数据段、IO流的缓冲区都拷贝一份,父子进程共享代码段。
5、fork函数调用成功后,父子进程就开始各自执行了,它们的先后顺序是不确定的,但可以通过某些实现来保证。
#include <stdio.h> #include <unistd.h> int main() { if(fork()) { printf("进程id:%d 父进程id:%d\n", getpid(), getppid()); while(1); } if(fork()) { printf("进程id:%d 父进程id:%d\n", getpid(),getppid()); while(1); } if(fork()) { printf("进程id:%d 父进程id:%d\n", getpid(), getppid()); while(1); } printf("进程id:%d 父进程id:%d\n", getpid(), getppid()); while(1); }
输出结果:
进程id:26146 父进程id:4594
进程id:26147 父进程id:26146
进程id:26148 父进程id:26147
进程id:26149 父进程id:26148
6、当总进程数超过系统的限制时,就无法再创建进程的了,此时fork函数会返回-1,执行失败。
7、孤儿进程:子进程还有运行,但父进程已经结束,此时子进程会被init(1)收养,子进程变成孤儿进程。
#include <stdio.h> #include <unistd.h> int main() { int pid = fork(); if(pid == 0) { printf("子进程:%d 父进程%d\n", getpid(), getppid()); sleep(2); printf("子进程:%d 父进程%d\n", getpid(), getppid()); } sleep(1); return; }
输出结果:
子进程:28010 父进程28009
子进程:28010 父进程1 // 此时父进程已消亡 子进程被init(1)收养 成为孤儿进程
8、僵尸进程:子进程已经死亡,但父进程没有及时回收子进程,此时子进程就会变成僵尸进程。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pid = fork();
if(pid == 0)
{
printf("子进程:%d\n", getpid());
exit(0);
}
while(1);
}
输出结果:
子进程:29928
通过ps命令查看子进程:29928状态:已经是Z表示僵尸进程。
29928 0.0 0.0 0 0 pts/0 Z+ 19:45 0:00 [a.out] <defunct>
9、父进程打开的文件和子进程是共享的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。