17、fork函数

简介: 1、定义 #include #include pid_t fork( void ); pid_t 是一个宏定义,其实质是int,被定义在#include中 返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1 2、函数说明: 一个现有进程可以调用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

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
#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

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
#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

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
#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.

参考

1http://baike.baidu.com/view/1952900.htm

2http://linux.die.net/man/2/fork

3】 不错的网页

http://www.csl.mtu.edu/cs4411/www/NOTES/process/fork/create.html

目录
相关文章
|
6月前
|
C语言
C语言 父进程fork()出的多个子进程在结束后,父进程如何回收?
我在网上找了半天都是在说wait()和waitpid()的详解或者是单个子进程的回收。答非所问。 很简单,根据wait()或者waitpid()的函数特性。没有子进程时返回-1。
56 0
|
6月前
|
程序员 Linux Shell
【CSAPP】进程控制 | 系统调用错误处理 | 进程状态 | 终止进程 | 进程创建 | 回收子进程 | 与子进程同步(wait/waitpid) | execve 接口
【CSAPP】进程控制 | 系统调用错误处理 | 进程状态 | 终止进程 | 进程创建 | 回收子进程 | 与子进程同步(wait/waitpid) | execve 接口
56 0
|
10月前
|
C++
C++中fork函数的使用及原理
C++中fork函数的使用及原理,在C++中,fork函数用于创建一个新的进程称为子进程,该进程与原始进程几乎完全相同。 fork函数的基本概况 fork() 函数调用成功之后,会有两个返回值。当前进程,也就是父进程返回子进程的 pid,子进程返回 0。如果函数调用错误,返回为-1。 #include <stdio.h> #include <unistd.h> int main(void) { int i = 0; printf("i\tson/pa\tppid\tpid\tfpid\n"); for (i = 0; i < 2; i++) { p
209 0
孤儿进程、僵尸进程和进程退出(通俗易懂)
孤儿进程、僵尸进程和进程退出(通俗易懂)
|
12月前
|
缓存 Linux 调度
fork函数、进程退出、进程等待(1)
在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
135 0
|
12月前
|
存储 编译器 调度
fork函数、进程退出、进程等待(2)
 return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返 回值当做 exit的参数。
122 0
|
Linux 调度
vfork() 函数
vfork() 函数
51 0
孤儿进程与僵尸进程
孤儿进程与僵尸进程
60 0
|
算法 物联网 Linux
创建进程 fork 函数|学习笔记
快速学习创建进程 fork 函数
147 0
创建进程 fork 函数|学习笔记
|
物联网 Linux 开发者
Waitpid 函数|学习笔记
快速学习 Waitpid 函数,“Waitpid 函数”,也是“等”。虽然功能和 “Wait” 相同,但是 “Waitpid” 实现的功能比 “Wait” 实现的功能更多。
124 0
Waitpid 函数|学习笔记