深入解析Linux中的fork函数
1、定义 #include <unistd.h> #include<sys/types.h> pid_t fork( void );
pid_t 是一个宏定义,其实质是int,被定义在#include<sys/types.h>中
返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
2、函数说明:
一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。File locks and pending signals are not inherited. 【3】
If the call to fork() is executed successfully, Unix will
① make two identical copies of address spaces, one for the parent and the other for the child.
② Both processes will start their execution at the next statement following the fork() call.
3、为什么fork会返回两次?
由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。因为fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。
After a new child process is created, both processes will execute the next instruction following the fork() system call.
调用fork之后,代码有两份,都从fork函数中返回。
Please note that Unix will make an exact copy of the parent's address space and give it to the child. Therefore, the parent and child processes have separate address spaces.
实例代码1:
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main(int argc,char**argv)
{
int pid=fork();
if(pid == -1)
{
print("error!");
}
else if(pid == 0)
{
print("This is the child process!");
}
else
{
print("This is the parent process! child process id = %d", pid);
}
return 0;
}
示例代码2:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define MAX_COUNT 200
#define BUF_SIZE 100
void main(void)
{
pid_t pid;
int i;
char buf[BUF_SIZE];
fork();
pid = getpid();
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
write(1, buf, strlen(buf));
}
}
为什么用write,而不用printf呢?because printf() is "buffered," meaning printf() will group the output of a process together,这样,会把子进程和父进程的输出混起来。所以用use the "unbuffered" write。
示例代码3:
#include <stdio.h>
#include <sys/types.h>
#define MAX_COUNT 200
void ChildProcess(void); /* child process prototype */
void ParentProcess(void); /* parent process prototype */
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0)
ChildProcess();
else
ParentProcess();
return 0;
}
void ChildProcess(void)
{
int i;
for (i = 1; i <= MAX_COUNT; i++)
printf(" This line is from child, value = %d\n", i);
printf(" *** Child process is done ***\n");
}
void ParentProcess(void)
{
int i;
for (i = 1; i <= MAX_COUNT; i++)
printf("This line is from parent, value = %d\n", i);
printf("*** Parent is done ***\n");
}
4、Error Codes
出错返回错误信息如下:
EAGAIN :达到进程数上限.
ENOMEM :没有足够空间给一个新进程分配.
fork()系统在Linux中的返回值是没有NULL的.
深入解析Linux中的fork函数的更多相关文章
- [fork]Linux中的fork函数详解
---------------------------------------------------------------------------------------------------- ...
- Unix/Linux中的fork函数
fork函数介绍 一个现有进程可以调用fork函数创建一个新进程.该函数定义如下: #include <unistd.h> pid_t fork(void); // 返回:若成功则在子进程 ...
- linux中的fork()函数以及标准I/O缓冲
1. fork()创建的新进程成为子进程.一次调用,两次返回,子进程的返回值是0,而父进程的返回值是新子进程的进程ID,如果出现错误,fork返回一个负值. 2. 可以通过fork返回的值来判断当前进 ...
- linux中的fork函数的基本用法
代码: #include <iostream> #include <string> #include <cstdio> #include <unistd.h& ...
- Linux编程之fork函数
在Linux中,fork函数的功能就是在一个进程中创建一个新的进程,当前调用fork函数的进程就是产生的新进程的父进程,新进程在以下也称为子进程.在新进程生成之后就会在系统中开始执行. 函数原型:pi ...
- 【Linux 进程】fork函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...
- 解析Linux中的VFS文件系统机制
转载:原文地址https://www.ibm.com/developerworks/cn/linux/l-vfs/ 1. 摘要 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2 ...
- 浅析linux中的fork、vfork和clone
各种大神的混合,做个笔记. http://blog.sina.com.cn/s/blog_7598036901019fcg.html http://blog.csdn.net/kennyrose/ar ...
- Linux 环境下 fork 函数和 exec 函数族的使用
前言 接触 Linux 已经有几个月了,以前在网上看各路大神均表示 Windows 是最烂的开发平台,我总是不以为然,但是经过这段时间琢磨,确实觉得 Linux 开发给我带来不少的便利.下面总结一下学 ...
随机推荐
- API得到Windows版本
API得到Windows版本 /** * Windows Version * https://msdn.microsoft.com/en-us/library/windows/desktop/dn48 ...
- ubuntu16.04下安装opencv
source url:http://blog.csdn.net/zhuiqiuk/article/details/5308505811 1 依赖包sudo apt-get install build- ...
- RX系列一 | ReactiveX根源 | 观察者模式分析
RX系列一 | ReactiveX根源 | 观察者模式分析 Rx的响应式编程算是很火了,对吧,但是我的工作基本上就不会接触,所以学习的比较晚,到现在才分享给大家,我们一点点的去学,当你看完这整个系列的 ...
- 一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的正负数之间相对顺序,比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时
#include <iostream> using namespace std; void txsort(int* arr, int len) { if (!arr || len == 1 ...
- 使用kprobes查看内核内部信息
前言:使用printk打印变量等方法,是调试内核的有效方法之一,但是这种方法必须重新构建并用新内核启动,调试效率比较低.以内核模块的方式使用kprobes.jprobes,就可以在任意地址插入侦测器, ...
- TreeMap倒序以及遍历
TreeMap倒序 TreeMap默认是按照Key给排序的,但是有的时候我们需要倒序,比如Key是日期,我们需要按照日期倒序显示(最近的时间在前面),类似下面这种情况 TreeMap倒序方法 tree ...
- PGM:基于模板的表示
http://blog.csdn.net/pipisorry/article/details/52537660 引言 概率图模型(无论贝叶斯网或马尔可夫网)在一个固定的随机变量集X上具体指定了一个联合 ...
- 剑指Offer——知识点储备-常用算法
剑指Offer--知识点储备-常用算法 快速排序 注:若排序是有序的,采用快排,则退化为冒泡排序. 解决这个问题,采用两个选取基准的方法 (1)随机选取基数(在这个区间内随机取一个数) 出现的恶劣情况 ...
- Python Tkinter小试
前两天看到一篇关于Python使用Tkinter 的博文,写的很好.就拿来研究了一下,改了改.现分享如下: 参考 代码 # coding:utf8 # python2.73 winxp ''''' 天 ...
- JAVA面向对象-----访问修饰符
访问修饰符是用来控制类.属性.方法的可见性的关键字称之为访问修饰符. 1.public 一个类中,同一包中,子类中,不同包中 2.protected 一个类中,同一包中,子类中 3.default 一 ...