进程控制1--fork vfork函数
linux系统调用fork()创建一个和当前进程完全相同的拷贝进程,其中父进程和子进程的代码段,堆栈段,数据段均独立
进程必须的4要点:
a.要有一段程序供该进程运行
b.进程专用的系统堆栈空间。
c.进程控制块,在linux中具体实现是task_struct
d.有独立的存储空间。
当一个进程缺少其中一个条件时候,我们称其为线程。
1.先看fork()的原型 :
#include<sys/types.h> /* 提供类型pid_t的定义 */
#include<unistd.h> /* 提供函数的定义 */
pid_t fork(void);
返回: 父进程中执行则返回子进程PID,子进程中执行返回0
现在进行一个例子,创建一个子进程,然后根据返回的 PID进行识别:
- /*test.c*/
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- main()
- {
- int count = 0;
- pid_t pid; /*此时仅有一个进程*/
- pid=fork(); /*此时已经有两个进程在同时运行*/
- if(pid<0) /*返回错误*/
- printf("error in fork!");
- else
- {
- if(pid==0) /*代码在子进程中执行*/
- printf("I am the child process, my count is %d,my process ID is %d/n",count,getpid());
- else /*代码在父进程中执行*/
- printf("I am the parent process,my count is %d, my process ID is %d/n",++count,getpid());
- }
- }
弄好后,在linux中键入:
$ gcc test.c -o test
$ ./test
在本次试验中
I am the parent process,my count is 1,my process ID is 3196
I am the child process, my count is 0,my process ID is 3776
从代码里面可以看出2者的pid不同,内存资源count是值得复制,父进程改变了count的值,而子进程中的count没有被改变。有人认为这样大批量的复制会导致执行效率过低。其实在复制过程中,子进程复制了父进程的task_struct,系统堆栈空间和页面表,这意味着上面的程序,我们没有执行count++前,其实子进程和父进程的count指向的是同一块内存。而当子进程改变了父进程的变量时候,会通过copy_on_write的手段为所涉及的页面建立一个新的副本。所以当我们执行++count后,这时候子进程才新建了一个页面复制原来页面的内容,基本资源的复制是必须的,而且是高效的。整体看上去就像是父进程的独立存储空间也复制了一遍。
在fork中,父子进程是独立开来的 ,并没有影响
2.vfork函数
vfork创建出来的不是真正意义上的进程,而是一个线程,因为它缺少了上面提到的进程的四要素的第4项,独立的内存资源,我们编一个程序练习:
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- main()
- {
- int count = 1;
- int child;
- printf("Before create son, the father's count is:%d/n", count);//打印没创建进程前
- if(!(child = vfork())) //创建子进程
- {
- printf("This is son, his pid is: %d and the count is: %d/n", getpid(), ++count);
- exit(1);
- } else
- {
- printf("After son, This is father, his pid is: %d and the count is: %d, and the child is: %d/n",
- getpid(), count, child);
- }
- }
然后编译,执行,得到下列结果:
Before create son, the father's count is:1
This is son, his pid is: 4048 and the count is: 2
After son, This is father, his pid is: 4048 and the count is: 2, and the child is: 2748
从这里我们看到,子进程和父进程是共享count的,也就是说,内存区是共享的
另外由vfork创造出来的子进程还会导致父进程挂起,除非子进程exit或者execve才会唤起父进程,看下面程序:
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- main()
- {
- int count = 1;
- int child;
- printf("Before create son, the father's count is:%d/n", count);
- if(!(child = vfork()))
- {//这里是子进程执行区
- int i;
- for(i = 0; i < 100; i++)
- {
- printf("This is son, The i is: %d/n", i);
- if(i == 70)
- exit(1);
- }
- printf("This is son, his pid is: %d and the count is: %d/n", getpid(), ++count);
- exit(1);//子进程退出
- }
- else
- {//父进程
- printf("After son, This is father, his pid is: %d and the count is: %d, and the child is: %d/n",
- getpid(), count, child);
- }
- }
好,编译通过,执行。。。
Before create son, the father's count is:1
This is son, The i is: 0
...
...
This is son, The i is: 68
This is son, The i is: 69
This is son, The i is: 70
After son, This is father, his pid is: 2564 and the count is: 1, and the child is: 2736
可以看到父进程总是等子进程执行完毕后才开始继续执行
进程控制1--fork vfork函数相关推荐
- 小何讲进程: Linux进程控制编程 (fork、vfork)
所谓进程控制,就是系统使用一些具有特定功能的程序段来创建进程.撤消进程以及完成进程在各种状态之间的转换, 从而达到多进程高效率并发执行和协调资源共享的目的.进程控制是进程管理和处理机管理的一个重要任务 ...
- 进程控制(2):进程操作
前言: 关于进程控制这块的好文很多,下面转载的这篇内容很丰富,也会举适当的栗子,与其写的一知半解不如参读学习别人的优秀博文,感谢原作,本系列摘录自:https://www.cnblogs.com/xi ...
- UNIX环境高级编程笔记之进程控制
本章重点介绍了进程控制的几个函数:fork.exec族._exit.wait和waitpid等,主要需要掌握的是父进程和子进程之间的运行机制,怎么处理进程的正常和异常终止.以及怎么让进程执行不同的程序 ...
- 实验四 linux进程控制实验报告,Linux系统进程控制操作系统实验报告4
实验课程名称:操作系统 实验项目名称Linux系统进程控制实验成绩 实验者专业班级组别 同组者实验日期年月日第一部分:实验分析与设计(可加页) 实验内容描述(问题域描述) 要求:掌握Linux系统中进 ...
- UNIX高级环境编程(9)进程控制(Process Control)- fork,vfork,僵尸进程,wait和waitpid...
本章包含内容有: 创建新进程 程序执行(program execution) 进程终止(process termination) 进程的各种ID 1 进程标识符(Process Identifiers ...
- Linux系统编程之进程控制(进程创建,fork函数,进程中止,进程等待,程序替换)
进程创建 fork()------复制,返回值,写时复制 vfork()创建子进程-子进程与父进程共用同一块虚拟地址空间, 为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出或者进行程序 ...
- linux创建进程fork函数和vfork函数
#include <unistd.h>pid_t fork(void);#include <sys/types.h>#include <unistd.h>pid_t ...
- linux c之创建进程fork和vfork函数之间的区别
1.函数简介 1).得到当前的进程id pid_t getpid(); 2).fork函数 要创建进程,必须调用fork函数, 系统调用fork用于派生一个进程,函数原型如下 #include< ...
- linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数
linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...
最新文章
- 2021年春季学期-信号与系统-第四次作业参考答案
- 初创公司谁来当你们的运维
- android+包+反编译,简单的Android之apk包反编译方法
- [代码整洁]自我感悟
- 吴恩达神经网络1-2-2_图神经网络进行药物发现-第2部分
- 今晚直播丨管中窥豹 - PostgreSQL、openGauss、达梦和OceanBase的初步介绍
- 搜索、推荐、广告中的曝光偏差问题
- Java基础,使用双循环嵌套,实现输出1-1000之间所有的素数,并统计有多少个
- Python 学习 Day23
- 许鹏:从零开始学习,Apache Spark源码走读
- SOLD2算法详解之1 backbone(CVPR2021 源码解析)
- GTK+ GUI库使用现状
- 考研数学1-考试大纲(2022年)
- Kettle的“增加序列”(自增字段)的使用
- 拉格朗日乘子法详解(Lagrange multiplier)
- 重装系统(无法开机时候操作方法)
- 学校计算机专业春联大全带横批,关于学校的春联带横批.doc
- 啊哈添柴挑战Java1221. 输出三角形
- 2022.2.20自制豆腐
- harries算子特征提取与图像匹配
热门文章
- 什么linux系统是中文的,什么是Linux系统
- mysql 性能状态_MySQL获取系统性能和状态_MySQL
- vue双向数据绑定v-model绑定单选框,复选框,下拉框
- 第8章 硬盘和显卡的访问与控制
- spring框架(三)mvc
- save(),saveOrUpdate(),merge()的区别
- 推荐几个配色和图标网站
- DB2 常用命令小结
- 用ASP.NET 2.0设计网络在线投票系统
- 46. Permutations