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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值