**
fork()函数
fork()函数的实质是一个系统调用(和write函数类似),其作用是创建一个新的进程,当一个进程调用它,完成后就出现两个几乎一模一样的进程,其中由fork()创建的新进程被称为子进程,而原来的进程称为父进程.子进程是父进程的一个拷贝,即子进程从父进程得到了数据段和堆栈的拷贝,这些需要分配新的内存;而对于只读的代码段,通常使用共享内存方式进行访问.
fork调用:
调用一次,返回两次,有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
例0
void main()
{
if (fork() == 0) {
printf("Hello from child\n");
}
else {
printf("Hello from parent\n");
}
exit(0);
}
输出结果:
Hello from parent
Hello from child
fork()返回值大于0时,运行父进程,输出“Hello from parent”;
fork()返回值为0时,运行子进程,输出“Hello from child”
例1
void main()
{
int x = 1;
pid_t pid = fork();
if (pid == 0) {
printf("Child has x = %d\n", ++x);
}
else {
printf("Parent has x = %d\n", --x);
}
printf("Bye from process %d with x = %d\n", getpid(), x);
exit(0);
}
输出结果:
Parent has x = 0
Bye from process 3269 with x = 0
Child has x = 2
Bye from process 3270 with x = 2
pid表示fork()返回值,getpid()获得进程号,父进程先运行,子进程后运行,两个进程运行过程中互不干扰
例2
void main()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("Bye\n");
exit(0);
}
输出结果:
L0
L1
Bye
Bye
L1
Bye
Bye
先运行父进程输出L0,fork()执行后一共有两个进程,L1输出两次,再次执行fork(),一共存在四个进程,Bye输出四次
例3`
void main()
{
printf("L0\n");
if (fork() != 0) {
printf("L1\n");
if (fork() != 0) {
printf("L2\n");
}
}
printf("Bye\n");
exit(0);
}
输出结果:
L0
L1
L2
Bye
Bye
Bye
父进程输出L0,执行fork()得到两个进程,返回值不为0,则父进程输出L1,再次执行fork(),得到两个进程,父进程输出L2,一共三个进程,一个父进程,两个子进程,最后输出三个Bye
例4
void main()
{
printf("L0\n");
if (fork() == 0) {
printf("L1\n");
if (fork() == 0) {
printf("L2\n");
exit(0);
}
}
printf("Bye\n");
}
输出结果:
L0
Bye
L1
Bye
L2
Bye
父进程输出L0,fork调用生成子进程1,输出L1和Bye,再次调用fork生成子进程2,输出L2和Bye,子进程1、2和父进程语句执行顺序不同
例5
void fork5()
{
if (fork() == 0) {
/* Child */
printf("Terminating Child, PID = %d\n", getpid());
exit(0);
} else {
printf("Running Parent, PID = %d\n", getpid());
while (1)
; /* Infinite loop */
}
}
输出结果:
Running Parent, PID = 4101
Terminating Child, PID = 4102
void fork5()
{
if (fork() == 0) {
/* Child */
printf("Running Child, PID = %d\n",
getpid());
while (1)
; /* Infinite loop */
} else {
printf("Terminating Parent, PID = %d\n",
getpid());
exit(0);
}
}
输出结果:
Terminating Parent, PID = 4090
Running Child, PID = 4091
例6
void main()
{
int child_status;
if (fork() == 0) {
printf("HC: hello from child\n");
exit(0);
} else {
printf("HP: hello from parent\n");
wait(&child_status);
printf("CT: child has terminated\n");
}
printf("Bye\n");
exit(0);
}
输出结果:
HP: hello from parent
HC: hello from child
CT: child has terminated
Bye
fork()调用生成子进程,父进程先运行,输出“HP:hello from parent”,调用wait()函数使父进程阻塞,子进程运行,输出“HC:hello from child”,子进程运行完,父进程继续运行,输出“CT:child hasterminated”、“Bye”