Linux进程
一、fork函数使用
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid_t pid2;
pid_t retpid;
pid = getpid();
printf("before fork : pid = %d\n",pid);
retpid = fork();
pid2 = getpid();
printf("behind fork : pid = %d\n",pid2);
if(pid == pid2){
printf("This is farther print , retpid = %d\n",retpid);
}else{
printf("This is son print ,retpid = %d, son pid = %d\n",retpid,getpid());
}
return 0;
}
二、实际应用场景
1、网络进程
一个父进程希望复制自己,使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的一父 进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一一个服务请求到达。
模拟场景:当用户输入1时,表示有用户接入。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int data = 10;
while(1){
printf("Please Input a data\n");
scanf("%d",&data);
if(data == 1){
pid = fork();
if(pid > 0){
}else if(pid == 0) {
while(1){
printf("do net reguest , pid = %d\n",getpid());
sleep(3);
}
}
}
else{
printf("wait ... do nothing\n");
}
}
return 0;
}
2、一个进程执行一个不同的程序
一个进程要执行一个不同的程序。这对shell是常 见的情况。在这种情况下,子进程从fork返回后立即调用exec。
三、vfork函数
注意事项:
vfork 直接使用父进程存储空间,不拷贝
vfork 保证子进程先运行,当子进程调用exit退出后,父进程才执行。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid > 0){
while(1){
printf("cnt = %d\n",cnt);
printf("This is farther print , father pid = %d\n",getpid());
sleep(1);
}
}else if(pid == 0) {
while(1){
printf("This is son print , son pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 3){
exit(0);
}
}
}
return 0;
}
四、进程退出
1、正常退出
main函数调用return
进程调用exit()函数,标准C库
进程调用_exit() 或者 _Exit(),属于系统调用
2、异常退出
调用abort
进程收到某些信号时,如 ctrl + C
五、父进程等待子进程退出
子进程退出状态不被收集会变成僵尸进程
父进程收集子进程退出码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid > 0){
wait(&status);//父进程阻塞等待子进程退出,关心子进程的退出状态,用WEXITSTATUS()这个宏来解析退出码。
printf("son quit , son status = %d\n",WEXITSTATUS(status));
while(1){
printf("cnt = %d\n",cnt);
printf("This is farther print , father pid = %d\n",getpid());
sleep(1);
}
}else if(pid == 0) {
while(1){
printf("This is son print , son pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}
孤儿进程
父进程如果不等待子进程退出,在子进程之前结束了自己的“生命”,此时子进程叫做“孤儿进程”。Linux避免系统存在过多孤儿进程,init进程(pid = 1)收留孤儿进程,变成孤儿进程的父进程。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
//孤儿进程,(子进程还没结束,父进程就先结束了)会被init(pid = 1)收留。
if(pid > 0){
printf("This is farther print , father pid = %d\n",getpid());
}else if(pid == 0) {
while(1){
printf("This is son print , son pid = %d , my father pid = %d\n",getpid(),getppid());
sleep(1);
cnt++;
if(cnt == 5){
exit(3);
}
}
}
return 0;
}