深入解析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 开发给我带来不少的便利.下面总结一下学 ...
随机推荐
- CRM客户关系管理系统(三)
第四章.kingadmin开发设计 4.1.kingadmin设计 自定义admin注册model的写法 crm/admin.py class CustomerAdmin(admin.ModelAdm ...
- SSA-一种适合中小型企业的新型服务架构
写在前面 好久好久没写了,最近刚换了工作,花了几天的时候熟悉了项目,接着就是功能的完善,随后就是对新项目的基础架构搭建. 看过Po主博客的都知道,Po主一直致力于推广.Net Core在微服务架构上的 ...
- Docker常见仓库Redis
Redis 基本信息 Redis 是开源的内存 Key-Value 数据库实现. 该仓库提供了 Redis 2.6 ~ 2.8.9 各个版本的镜像. 使用方法 默认会在 6379 端口启动数据库. $ ...
- iOS Exception Code 之 Magic Number
https://en.wikipedia.org/wiki/Hexspeak iOS Exception Code 之 Magic Number 备忘.
- APP自动化框架LazyAndroid使用手册(1)--框架简介
作者:cryanimal QQ:164166060 APP自动化简介 APP自动化,即通过自动化的方式,对APP施行一系列的仿按键输入.触摸屏输入.手势输入等操作,以达到对APP的功能进行自动化测试 ...
- 从Dynamics CRM2011到Dynamics CRM2016的升级之路
CRM的产品更新特别快,特别是最近的几个版本,很多客户依旧停留在2011甚至是4.0,也经常会听到有人问2011能不能升级至最新版,2013能不能升级至最新版,本文将简单演示下从2011升级到2016 ...
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...
- [csdn markdown]使用摘记二 快捷键及导入导出Markdown文件
csdn推出了新的编辑器markdown,对于习惯使用离线编辑的人员来说是个大的福利,比如上班的时候,不能联网,但是又有好些知识点需要记录,等到下班了呢,又想直接把这些排版格式良好的文件直接上传到cs ...
- linux 最大文件描述符
Linux对应用程序能打开的的最大文件描述符数量有两个层次的限制:用户级限制和系统级限制. 用户级限制是指目标用户运行的所有进程总共能打开的文件描述符数. 系统级的限制是指所有用户总共能打开的文件描述 ...
- 字符编码(ASCII、ANSI、GB2312、UTF-8等)系统梳理
引言 在显示器上看见的文字.图片等信息在电脑里面其实并不是我们看见的样子,即使你知道所有信息都存储在硬盘里,把它拆开也看不见里面有任何东西,只有些盘片.假设,你用显微镜把盘片放大,会看见盘片表面凹凸不 ...