一、fork函数

要创建一个进程,最基本的系统调用是fork,系统调用fork用于派生一个进程,函数原型如下: pid_t fork(void)  若成功,父进程中返回子进程ID,子进程中返回0,若出错返回-1;fork()系统调用的作用是复制一个进程,当一个进程调用它,完成个就出现两个几乎一摸一样的进程,新进程是子进程,原来的进程是父进程。子进程是父进程的一个拷贝,子进程从父进程那里得到了代码段和数据段的拷贝。Fork函数调用一次,但返回两次,两次返回的区别是子进程的返回值是0,父进程的返回值是子进程返回值的进程ID。Fork返回后,子进程和父进程都从调用fork函数的下一条语句开始执行。

程序一是fork调用:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main (void)
{
int count = 0;
pid_t pid; /*此时仅有一个进程*/
pid = fork(); /*此时已经有两个进程在同时运行*/
if(pid < 0)
{
printf("error in fork!");
exit(1); /* fork出错退出*/
}
else if(pid==0)
printf("I am the child process, the count is %d, my process ID is %d\n",count,getpid());
else
printf("I am the parent process, the count is %d, my process ID is %d\n",++count,getpid());
return 0;
}

必须了解一个概念:在语句pid = fork();之前,只有一个进程在执行这段代码,该语句之后,就变成两个进程在执行了,且二者代码部分完全相同,将要执行的下一条语句都是 if(pid<0)。

Fork函数的奇妙之处是仅仅被调用一次,却返回了两次,可能有三种取值:

1,在父进程中,fork返回新创建子进程的ID

2,在子进程中,fork返回0

3,出现错误时,返回负值

二、linux下另一个创建进程的方式是vfork,原型如下:pid_t vfork(void);

若成功,父进程中返回子进程ID,子进程中返回0,若出错返回-1;fork与vfork是有区别的,fork要拷贝父进程的数据段,而vfork不需要完全拷贝父进程的数据段,在子进程没有调用exec或者exit函数之前,子进程会与父进程共享数据段。在fork中子进程与父进程的执行顺序不确定,而在vfork中,子进程先运行,父进程挂起,直到子进程调用了exec或者exit函数,父进程才被执行。

程序二说明了vfork创建后父子进程是共享数据段的。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main (void)
{
int count = 1;
int child;
printf("Before create son, the father's count is:%d\n", count); /*创建进程之前*/
child = vfork(); /*此时已经有两个进程在同时运行*/
if(child < 0)
{
printf("error in vfork!");
exit(1); /* fork出错退出*/
}
if(child==0) /*子进程*/
{
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);
}
return 0;
}

在子进程中修改了count值,在父进程中输出count时是子进程修改后的值,这说明父进程和子进程是共享count,也就是二者是共享内存区的。

程序三说明由vfork创造出来的子进程是会导致父进程挂起,直到子进程执行xec或者exit函数才会唤醒父进程

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main (void)
{
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);
}
return 0;
}

从中可以看书父进程是在等子进程执行完毕后才开始执行的。

fork与vfork详解的更多相关文章

  1. Fork/Jion框架详解

    ◆Fork/Jion框架可以干什么◆ 如果你要处理1万条数据,但是你的能力暂时还不够,一个简单快捷的办法就是你可以把每次只处理100条,等到处理100次之后再把所有的结果聚合起来你就处理完了这1万条数 ...

  2. Fork/Join框架详解

    Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.Fork/Join框架要完成两件事情: 1.任务分 ...

  3. fork()详解

    参照: http://blog.csdn.net/jason314/article/details/5640969 http://coolshell.cn/articles/7965.html

  4. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  5. fork()函数详解

    linux中fork()函数详解(原创!!实例讲解) (转载)    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程 ...

  6. Linux环境fork()函数详解

    Linux环境fork()函数详解 引言 先来看一段代码吧, 1 #include <sys/types.h> 2 #include <unistd.h> 3 #include ...

  7. linux --> fork()详解

    fork()详解 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个 ...

  8. 【转】linux 中fork()函数详解

    在看多线程的时候看到了这个函数,于是学习了下,下面文章写的通俗易懂,于是就开心的看完了,最后还是很愉快的算出了他最后一个问题. linux 中fork()函数详解 一.fork入门知识 一个进程,包括 ...

  9. Linux中fork()函数详解(转载)

    linux中fork()函数详解 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事, ...

随机推荐

  1. html中的table在android端显示

    转载请注明出处:http://blog.csdn.net/u012338845/article/details/46773245 開始都是用Html.fromHtml(source).来显示html的 ...

  2. GNU GPL介绍

    怎样在程序中使用GNU许可证       不管使用哪种许可证,使用时须要在每一个程序的源文件里加入两个元素:一个版权声明和一个复制许可声明.说明该程序使用GNU许可证进行授权.另外在声明版权前应该说明 ...

  3. ps中图层混合模式、多图层叠加、不透明度、填充、图层样式详解

    图像领域中,通过进行一下想法的时候,都要通过用ps看下是不是合理,而ps中图层是必用的一个功能,下面详解一下图层有关的叠加原理. 基本顺序是图层从下往上继续, 先计算图层的填充,再计算样式.最后计算不 ...

  4. Java 5种字符串拼接方式性能比较。

    最近写一个东东,可能会考虑到字符串拼接,想了几种方法,但对性能未知,于是用Junit写了个单元测试. 代码如下: import java.util.ArrayList; import java.uti ...

  5. OCP读书笔记(12) - 执行闪回数据库

    闪回数据库使用的是闪回日志,闪回日志存在于闪回目录(也就是快速闪回区中)闪回日志:就是数据块修改之前的镜像,简称前像 1.查看闪回目录的位置:show parameter recovery 如果闪回目 ...

  6. JDBC/XML的一些基本使用

    原文:JDBC/XML的一些基本使用 一.知识点题目:JDBC核心API的使用 关键字:JDBC核心API 内容: 1)加载JDBC驱动: Oracle:Class.forName(“oracle.j ...

  7. android 项目中使用对话框统一封装

    近期在做拼车项目中使用到了一些对话框,而且在非常多地方都使用到了,既然非常多地方使用到,那么肯定要封装一下,

  8. Struts2 学习第一步准备工作

    第一步:安装下载MyEclispe10 对于MyEclispe的下载安装就不再详述了. 第二步:下载Struts-2.3.15 Struts-2.3.15下载地址: http://struts.apa ...

  9. JVM学习03_new对象的内存图讲解,以及引出static方法(转)

    目录 -=-讲解对象创建过程中,-=-堆内存和栈内存的情况 -=-构造函数对类对象的成员变量的初始化过程 -=-构造函数出栈 -=-类的方法在不访问类对象的成员变量时造成的内存资源浪费怎么解决? -= ...

  10. php将中文插入数据库出现乱码

    通过php向mysql数据库插入数据,然后在数据库中查看的时候全是乱码(中文),但是取出之后放在页面上仍然正常.就是通过数据库查看的时候全是乱码不能阅读. mysql以UTF-8编码来保存中文,页面提 ...