一、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. newlisp 注释生成文档

    最近写了一个newlisp_armory库,用来实现一些newlisp自身不支持的操作.比如跨windows和ubuntu的目录拷贝功能等. 自己用的时候,发现没有API reference文档参考, ...

  2. Android实战开发租赁管理软件(适配UI,数据的存储,多线程下载)课程分享

    亲爱的网友,我这里有套课程想和大家分享,假设对这个课程有兴趣的,能够加我的QQ2059055336和我联系. 课程内容简单介绍 我们软件是基于移动设备的.所以我们必定的选择了安卓作为我们的开发工具.课 ...

  3. Direct UI

    在界面开发中,眼下DirectUI是个热门的技术名称,由于众多的知名公司都是用DirectUI方式作出了非常炫丽的界面.而对于大多数熟悉Win32控件,熟悉MFC开发的开发者来说,我们应该做何选择? ...

  4. eclipse中我要同时看两个console

    eclipse中我要同时看两个console 有一个按钮“New Console View”,可以让你再建一个Console,还有一个按钮“Display Selected Console”,可以在两 ...

  5. hdu4635(强连通缩点)

    传送门:Strongly connected 题意:求最多可以加多少边,使得最新的图还不是强连通图. 分析:最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数 ...

  6. RCP开发中错误:java.lang.RuntimeException: WARNING: Prevented recursive attempt to activate part...

    在做RCP的eclipse插件开发时,启动管理软件界面时,总是报如下错误 : !ENTRY org.eclipse.ui.workbench 4 0 2012-05-25 18:44:21.306 ! ...

  7. Codeforces 461B - Appleman and Tree 树状DP

    一棵树上有K个黑色节点,剩余节点都为白色,将其划分成K个子树,使得每棵树上都仅仅有1个黑色节点,共同拥有多少种划分方案. 个人感觉这题比較难. 如果dp(i,0..1)代表的是以i为根节点的子树种有0 ...

  8. Android入门之简单短信发送器

    效果图: manifest.xml 文件中加入  <uses-permission android:name="android.permission.SEND_SMS"/&g ...

  9. vim忽略大写和小写查找配置

    作者:zhanhailiang 日期:2014-12-17 默认 vim 的查找是区分大写和小写,可通过下面两种方式实现忽略大写和小写查找 set ic? noignorecase 1 指令设定: : ...

  10. Cannot instantiate the type List&lt;Integer&gt;

    在使用java.util.List; 的时候,把语句写成了: List<Integer> arr = new List<Integer>(); 导致错误: Cannot ins ...