进程基础1 --- 进程源语fork

一、进程源语
系统提供的进程相关API完成多进程开发。
fork 进程创建, exec 进程功能重载 ,wait 进程回收,waitpid 进程回收。 (wait函数的升级版)
二、fork
1、fork的英文原义是叉子,用叉子的形状表示进程关系。
在这里插入图片描述
父进程调用fork,通知内核帮我创建一个进程。
2、fork函数
fork的核心功能:
1)_CREAT(进程创建) 只是一个空壳
2)_CLONE(克隆,进程初始化) 将父进程的资源继承拷贝给子进程

pid_t pid;  //进程pid类型,用户存储进程id
pid_t fork(void);  //fork函数可以创建一个子进程

1)fork函数调用一次返回两次
2)在父进程中返回子进程的pid (pid > 0)
3)在子进程中返回 0 (pid == 0)
4)失败返回-1
这四句话不理解没有关系,后面你一定会理解。

#include<stdio.h>
#include<unistd.h>
int main()
{
	pid_t pid;
	pid = fork();
	printf("process starting ... \n");
	while(1)
		sleep(1); //Linux下sleep单位为s	
	return 0;
}

在这里插入图片描述
在这里插入图片描述
(ps aux 查看系统进程信息)
3、默认情况下父进程的工作以及数据会继承给子进程,子进程直接使用。内核空间部分拷贝,可以继承的拷贝给子进程一份,其他的重新生成。用户空间完全拷贝。子进程将父进程的资源拷贝一份,子进程修改资源与父进程无关。
那就会产生一个问题,代码段在用户区会完全拷贝给子进程,那么就意味着 fork这段代码也会拷贝给子进程,这不就会一直创建进程吗?父创建子, 子创建孙 … … 但是实际上 通过我们刚才执行程序发现,这种情况并没有出现。
关于父子进程代码执行问题: 父进程从起始位置向下执行到末尾 ,子进程从fork之后执行到末尾 。(暂时可以先这样理解 但是其实是不准确的,我们下面会详细讲解)
4、区分父子进程工作区
让父子进程模型中每一个成员拥有独立的任务: FORK函数调用一次返回两次,可以通过返回值区分父子进程。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
	pid_t pid;
	pid = fork();
	if(pid > 0){
		printf("parent process running ..\n");
                while(1)
                       sleep(1);
	}else if(pid == 0){
		printf("child process running..\n");
		while(1)
                       sleep(1);
	}else{
		perror("fork call fialed");
		exit(0);
	}
	return 0;
	
}

在这里插入图片描述
5、fork被父子进程执行,每个进程执行一部分。
父进程和子进程其实都会走fork这个语句,只是执行fork语句里面的内容不同,linux下正常程序结束都会return 0,我们上面提到fork函数里面由两个主要的模块,第一_CREATE,创建出来一个新的进程,只是一个空壳,经过第二_CLONE以后有了资源,会返回进程的pid,也就是说父进程调用fork走完这两个模块后得到一个返回的pid,也就是子进程的pid,而子进程调用fork是不走上面两部分的,因为上面两部分也不归他管,它也没什么可走的,直接return 0,得到返回值0。现在再看fork函数调用一次但返回两次这句话也就不难理解了。
6、一父多子进程模型(多进程并发模型)

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{   
	int i;
	pid_t pid;
	for(i = 0;i < 10;i++){
		pid = fork();
		if(pid == 0)
			break;
	}
	if(pid > 0){
		printf("parent process running ...\n");
		while(1)
			sleep(1);
	}else if(pid == 0){
		printf("child code [%d] process running ...\n",i);
		while(1)
			sleep(1);
	}else{
		perror("fork call failed");
		exit(0);
	}
	return 0;
}

我们来分析一下for循环这段代码,因为可能除了这里其他地方也没有什么难以理解的,我们的本意是让一个父进程创建10个子进程,当 i 等于0的时候创建出一个子进程0号,子进程0号继承过来的i 也等于0,在for循环里并不会出去,而是会继续走for循环,也就是子进程0号也会fork出子进程,i 等于1的时候,父进程创建出来一个子进程1号,子进程1号继承过来的 i 等于1,也会在for循环里,也会fork出子进程,而子进程的子进程根据继承的 i 的值还会继续创建子进程 … … 所以,我们并不想要父进程创建出的子进程接着执行for循环,就要加上判断,发现是子进程,直接结束循环。
在这里插入图片描述
输出顺序不按照0~9是正常的。
在这里插入图片描述
算父进程,一共11个。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值