fork函数的原形是: pid_t fork(void);
使用它必须包含两个头文件:<sys/types.h>以及<unistd.h>。
它的功能是啥呢?很简单,就是新建一个子进程。
许多时候我们需要在一个进程中执行另一个程序,但又不想影响本进程的运行,那么可以创建一个子进程,然后再进行处理。
那新建的子进程的特点是什么?它其实就是父进程的复制品,继承了几乎所有能继承的,包括标准输出输入、变量值等等。注意这里是复制品,它们的内容几乎一样,但不代表共享了一份内存。。
一些资料上写:fork函数被调用一次,返回两次。在父进程返回子进程的pid,在子进程返回0。这话该怎么理解呢?
我们做一个试验:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid = getpid();
printf("my process id is %d!/n", pid);
pid = fork(); // create a child process
if(pid == 0)
{
// in the child process
printf("I am child process, my process id is %d!/n", getpid());
_exit(0);
}
else if(pid > 0)
{
// in the parent process
printf("I am parent process, my process id is %d!/n", getpid());
}
else
{
// unabled create child process
perror("unabled create child process");
}
}
#gcc -o fork fork.c
#./fork
输出结果为:
my process id is 5579!
I am child process, my process id is 5580!
I am parent process, my process id is 5579!
很奇怪,既然是父进程的复制品,为什么只输出一次“my process id is 5579!”而不是父进程和子进程都输出一次呢?其实很简单,这个复制品是连运行状态都复制了,前边执行过的就不会再执行,而子进程是从那一句pid = fork(); 开始执行的,在这一刻,它返回了0,而父进程的fork是返回了子进程的pid。然后从这一句开始,父子两个进程就分道扬镖了,各自执行自己的代码。
那两者数据不共享是什么意思呢?
再做个实验:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid = getpid();
int i = 12;
int status = 0;
if(pid = fork())
{
// do nothing
}
else if(pid == 0)
{
i = 111;
}
else if(pid < 0)
{
perror("unabled create a child process/n");
exit(1);
}
if(pid > 0)
{
if((pid = waitpid(pid, &status, 0)) < 0)
{
perror("waitpid error");
exit(1);
}
}
printf("i is %d/n", i);
return 0;
}
输出结果为:
i is 111
i is 12
在这段程序中,父进程调用waitpid等待子进程结束才继续运行输出i的值,也就是说第一行是子进程输出的,第二行是父进程输出的。可以看到i的值并不一样,虽然子进程修改了i的值,但对于父进程中的i是完全没有影响的,i的值是复制了,但它并不是同一份内存。
如果要共享同一份内存,就要涉及到多线程的知识了。
结束子进程
结束子进程不用exit(0),而使用_exit(0)。这是因为_exit(0)在结束进程时,不对标准I/O流进行任何操作。而exit(0)则会关闭进程的所有标准I/O流。
使用它必须包含两个头文件:<sys/types.h>以及<unistd.h>。
它的功能是啥呢?很简单,就是新建一个子进程。
许多时候我们需要在一个进程中执行另一个程序,但又不想影响本进程的运行,那么可以创建一个子进程,然后再进行处理。
那新建的子进程的特点是什么?它其实就是父进程的复制品,继承了几乎所有能继承的,包括标准输出输入、变量值等等。注意这里是复制品,它们的内容几乎一样,但不代表共享了一份内存。。
一些资料上写:fork函数被调用一次,返回两次。在父进程返回子进程的pid,在子进程返回0。这话该怎么理解呢?
我们做一个试验:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid = getpid();
printf("my process id is %d!/n", pid);
pid = fork(); // create a child process
if(pid == 0)
{
// in the child process
printf("I am child process, my process id is %d!/n", getpid());
_exit(0);
}
else if(pid > 0)
{
// in the parent process
printf("I am parent process, my process id is %d!/n", getpid());
}
else
{
// unabled create child process
perror("unabled create child process");
}
}
#gcc -o fork fork.c
#./fork
输出结果为:
my process id is 5579!
I am child process, my process id is 5580!
I am parent process, my process id is 5579!
很奇怪,既然是父进程的复制品,为什么只输出一次“my process id is 5579!”而不是父进程和子进程都输出一次呢?其实很简单,这个复制品是连运行状态都复制了,前边执行过的就不会再执行,而子进程是从那一句pid = fork(); 开始执行的,在这一刻,它返回了0,而父进程的fork是返回了子进程的pid。然后从这一句开始,父子两个进程就分道扬镖了,各自执行自己的代码。
那两者数据不共享是什么意思呢?
再做个实验:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid = getpid();
int i = 12;
int status = 0;
if(pid = fork())
{
// do nothing
}
else if(pid == 0)
{
i = 111;
}
else if(pid < 0)
{
perror("unabled create a child process/n");
exit(1);
}
if(pid > 0)
{
if((pid = waitpid(pid, &status, 0)) < 0)
{
perror("waitpid error");
exit(1);
}
}
printf("i is %d/n", i);
return 0;
}
输出结果为:
i is 111
i is 12
在这段程序中,父进程调用waitpid等待子进程结束才继续运行输出i的值,也就是说第一行是子进程输出的,第二行是父进程输出的。可以看到i的值并不一样,虽然子进程修改了i的值,但对于父进程中的i是完全没有影响的,i的值是复制了,但它并不是同一份内存。
如果要共享同一份内存,就要涉及到多线程的知识了。
结束子进程
结束子进程不用exit(0),而使用_exit(0)。这是因为_exit(0)在结束进程时,不对标准I/O流进行任何操作。而exit(0)则会关闭进程的所有标准I/O流。