linux c学习笔记----进程创建(fork,wait,waitpid)
1.pid_t fork();
(1)当一个进程调用了fork 以后,系统会创建一个子进程.这个子进程和父进程不同的地方只有他的进程ID 和父进程ID,其他的都是一样.就象符进程克隆(clone)自己一样.
(2)为了区分父进程和子进程,我们必须跟踪fork 的返回值. 当fork 掉用失败的时候(内存不足或者是用户的最大进程数已到)fork 返回-1,否则fork 的返回值有重要的作用.对于父进程fork 返回子进程的ID,而对于fork 子进程返回0.我
们就是根据这个返回值来区分父子进程的.
(3)一旦子进程被创建,父子进程一起从fork 处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞直
到子进程完成任务.这个时候我们可以调用wait 或者waitpid 系统调用.
vfork(建立一个新的进程)
|
相关函数
|
wait,execve |
|
表头文件
|
#include<unistd.h> |
|
定义函数
|
pid_t vfork(void); |
|
函数说明
|
vfork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。Linux 使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。注意,Linux不保证子进程会比父进程先执行或晚执行,因此编写程序时要留意 |
|
死锁或竞争条件的发生。
|
|
|
返回值
|
如果vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。如果vfork 失败则直接返回-1,失败原因存于errno中。 |
|
错误代码
|
EAGAIN 内存不足。ENOMEM 内存不足,无法配置核心所需的数据结构空间。 |
|
范例
|
#include<unistd.h> main() { if(vfork() = =0) { printf(“This is the child process\n”); }else{ printf(“This is the parent process\n”); } } |
|
执行
|
this is the parent process this is the child process |
wait(等待子进程中断或结束) |
|
表头文件
|
#include<sys/types.h> #include<sys/wait.h> |
|
定义函数
|
pid_t wait (int * status); |
|
函数说明
|
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则 |
|
参数
|
status可以设成NULL。子进程的结束状态值请参考waitpid()。 |
|
返回值
|
如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。 |
waitpid(等待子进程中断或结束)
|
表头文件
|
#include<sys/types.h> #include<sys/wait.h> |
|
定义函数
|
pid_t waitpid(pid_t pid,int * status,int options); |
|
函数说明
|
waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则参数status可以设成NULL。参数pid为欲等待的子进程识别码,其他数值意义如下: pid<-1 等待进程组识别码为pid绝对值的任何子进程。 pid=-1 等待任何子进程,相当于wait()。 pid=0 等待进程组识别码与目前进程相同的任何子进程。 pid>0 等待任何子进程识别码为pid的子进程。 参数option可以为0 或下面的OR 组合 WNOHANG 如果没有任何已经结束的子进程则马上返回,不予以等待。 WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。 子进程的结束状态返回后存于status,底下有几个宏可判别结束情况 WIFEXITED(status)如果子进程正常结束则为非0值。 WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED 来判断是否正常结束才能使用此宏。 WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真 WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED 来判断后才使用此宏。 WIFSTOPPED(status)如果子进程处于暂停执行情况则此宏值为真。一般只有使用WUNTRACED 时才会有此情况。 WSTOPSIG(status)取得引发子进程暂停的信号代码,一般会先用WIFSTOPPED 来判断后才使用此宏。 |
|
返回值
|
如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。 |
|
|
例子:#include <unistd.h>
- <span style="font-size: small;">#include <sys/types.h>
- #include <sys/wait.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <math.h>
- int main(void) {
- pid_t child,child2;
- int status;
- printf("This will demostrate how to get child status\n");
- if ((child = fork()) == -1) {
- printf("Fork Error :%s\n", strerror(errno));
- exit(1);
- } else if (child == 0) {
- child2 = fork();
- if(child2 == 0)
- printf("I am the child2:%ld\n",getpid());
- int i;
- printf("I am the child:%ld\n", getpid());
- for (i = 0; i < 1000000; i++) sin(i);
- i = 5;
- printf("I exit with %d\n", i);
- exit(i);
- }
- while (((child = waitpid(getpid(),&status,0)) == -1)&(errno == EINTR));
- if (child == -1)
- printf("Wait Error:%s\n", strerror(errno));
- else if (!status)
- printf("Child %ld terminated normally return status is zero\n",
- child);
- else if (WIFEXITED(status))
- printf("Child %ld terminated normally return status is %d\n",
- child, WEXITSTATUS(status));
- else if (WIFSIGNALED(status));
- printf("Child %ld terminated due to signal %d znot caught\n",
- child, WTERMSIG(status));
- getchar();
- return (EXIT_SUCCESS);
- }
- </span>
linux c学习笔记----进程创建(fork,wait,waitpid)的更多相关文章
- linux内核学习之六 进程创建过程学习
一 关于linux进程概念的补充 关于进程的基本概念这里不多说,把自己的学习所得作一些补充: 1. 在linux内核中,系统最多可以有64个进程同时存在. 2.linux进程包含的关键要素:一段可执行 ...
- linux c学习笔记----线程创建与终止
进程原语 线程原语 描述 fork pthread_create 创建新的控制流 exit pthread_exit 从现有的控制流中退出 waitpid pthread_join 从控制流中得到退出 ...
- Linux内核学习笔记-2.进程管理
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- Linux内核学习笔记二——进程
Linux内核学习笔记二——进程 一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...
- Linux系统学习笔记:文件I/O
Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...
- 操作系统学习笔记----进程/线程模型----Coursera课程笔记
操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...
- linux kernel学习笔记-5内存管理_转
void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...
- 尚硅谷韩顺平Linux教程学习笔记
目录 尚硅谷韩顺平Linux教程学习笔记 写在前面 虚拟机 Linux目录结构 远程登录Linux系统 vi和vim编辑器 关机.重启和用户登录注销 用户管理 实用指令 组管理和权限管理 定时任务调度 ...
- JUC学习笔记——进程与线程
JUC学习笔记--进程与线程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的进程与线程部分 我们会分为以下几部分进行介绍: 进程与线程 并发与并行 同步与异步 线程详解 进程与线程 ...
随机推荐
- zepto的tap事件的穿透分析
首先是什么情况下会发生zepto(tap)的事件穿透: 当一个弹出层用tap点击之后这个层隐藏或者是移走,都会触发下面对应位置的点击事件(click)和一些标签的默认行为(a标签的跳转.input获取 ...
- 对于a标签点击之后可以发邮件和打电话的功能实现
<ul> <li><i class="phone"></i><a href="tel:021-69976089&qu ...
- Java NIO 概述
Channel 和 Buffer 标准的Java IO编程接口是面向字节流和字符流的 而 NIO 是面向通道和缓冲区的 数据总是从通道中读到Buffer中,或者从Buffer写入通道中 NIO可以理解 ...
- codevs 3012 线段覆盖 4 & 3037 线段覆盖 5
3037 线段覆盖 5 时间限制: 3 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 数轴上有n条线段,线段的两端都 ...
- FusionCharts参数的详细说明和功能特性(转)
功能特性animation 是否动画显示数据,默认为1(True)showNames 是否显示横向坐标轴(x轴)标签名称ro ...
- usb驱动开发3之先看core
上节中看到usb目录中有一个core目录,凡是认识这个core单词的人都会想要先看看它是什么,对不?用LDD3中一幅图,来表述usb core所处地位. usb core负责实现一些核心的功能,为别的 ...
- WEB 安全之 SQL注入<一> 盲注
SQL注入是一个比较"古老"的话题,虽然现在存在这种漏洞的站点比较少了,我们还是有必要了解一下它的危害,及其常用的手段,知己知彼方能百战不殆.进攻与防守相当于矛和盾的关系,我们如果 ...
- angularjs中只显示选中的radio的值
angularjs中,只显示选中的radio的值.主要是相同的radio,name属性值要相同还有ng-model的值要相同,同时要指定value值.这样选中的时候就会在下面的div中显示选中的值了. ...
- ASP.NET Web API路由规则(二)
默认的规则 在ASP.NET MVC4中 global.asax.cs代码中并无注册默认路由规则的代码 代码如下: public class WebApiApplication : System.We ...
- JS clientHeight,scrollHeight,offsetHeight,scrollTop,offsetTop概念
JS滚动页面到某一位置时触发指定事件能够增强用户体验或是提高性能,其中使用最多的场景是加载更多,当鼠标滚动至页面下方时,自动加载下一页的内容.另一个常用的场景是当用户滚动至页面某一地方时,页面会给出提 ...