吾爱程序员:这里有好玩的游戏和软件
当前位置:首页C语言教程 → C语言中的fork()

C语言中的fork()

来源:网络 | 更新时间:2022-02-06 07:24:34
fork 系统调用用于创建一个新进程,称为子进程,它与进行 fork() 调用的进程(父进程)同时运行。创建新的子进程后,两个进程都将执行 fork() 系统调用之后的下一条指令。子进程使用与父进程相同的 pc(程序计数器)、相同的 CPU 寄存器、相同的打开文件。 它不接受任何参数并返回一个整数值。下面是 fork() 返回的不同值。 负值:创建子进程不成功。 :返回新创建的子进程。 正值:返回给父级或调用者。该值包含新创建的子进程的进程 ID。 请注意,以上程序不能在 Windows 环境下编译。
  • 预测以下程序的输出:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{

// make two process which run same
// program after this instruction
fork();

printf("Hello world!n");
return 0;
}
输出:
Hello world!
Hello world!
  • 计算打印 hello 的次数:
#include <stdio.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hellon");
return 0;
}
输出:
hello
hello
hello
hello
hello
hello
hello
hello
打印“hello”的次数等于创建的进程数。Total Number of Processes = 2 n,其中 n 是 fork 系统调用的数量。所以这里 n = 3, 2 3 = 8 让我们为这三行添加一些标签名称:
fork ();   // Line 1
fork ();   // Line 2
fork ();   // Line 3

       L1       // There will be 1 child process 
    /          // created by line 1.
  L2      L2    // There will be 2 child processes
 /      /     //  created by line 2
L3  L3  L3  L3  // There will be 4 child processes 
                // created by line 3
所以总共有八个进程(新的子进程和一个原始进程)。 如果我们想将进程之间的关系表示为树层次结构,则如下所示: 主进程:P0 第一次fork创建的进程:P1 第二次fork创建的进程:P2、P3 第三次fork创建的进程:P4、P5、P6、P7
             P0
         /   |   
       P1    P4   P2
      /            
    P3    P6         P5
   /
 P7
  • 预测以下程序的输出:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkexample()
{
// child process because return value zero
if (fork() == 0)
printf("Hello from Child!n");

// parent process because return value non-zero.
else
printf("Hello from Parent!n");
}
int main()
{
forkexample();
return 0;
}
输出:
1.
Hello from Child!
Hello from Parent!
     (or)
2.
Hello from Parent!
Hello from Child!
  • 在上面的代码中,创建了一个子进程。fork() 在子进程中返回 0,在父进程中返回正整数。 在这里,两个输出是可能的,因为父进程和子进程同时运行。所以我们不知道操作系统会先把控制权交给父进程还是子进程。 重要提示:父进程和子进程运行的是同一个程序,但这并不意味着它们是相同的。OS为这两个进程分配不同的数据和状态,这些进程的控制流可以不同。请参见下一个示例:
  • 预测以下程序的输出:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

void forkexample()
{
int x = 1;

if (fork() == 0)
printf("Child has x = %dn", ++x);
else
printf("Parent has x = %dn", --x);
}
int main()
{
forkexample();
return 0;
}
输出:
Parent has x = 0
Child has x = 2
     (or)
Child has x = 2
Parent has x = 0
在这里,一个进程中的全局变量更改不会影响其他两个进程,因为两个进程的数据/状态不同。而且父母和孩子同时运行,所以两个输出是可能的。

fork() 与 exec()

fork 系统调用创建一个新进程。fork() 创建的新进程是当前进程的副本,但返回值除外。exec() 系统调用用新程序替换当前进程。 锻炼:
  • 一个进程执行以下代码:
for (i = 0; i < n; i++)
fork();
创建的子进程总数为:(GATE-CS-2008) (A) n (B) 2^n – 1 (C) 2^n (D) 2^(n+1) – 1;
  • 考虑以下代码片段:
if (fork() == 0) {
a = a + 5;
printf("%d, %dn", a, &a);
}
else {
a = a –5;
printf("%d, %dn", a, &a);
}
设 u, v 是父进程打印的值,x, y 是子进程打印的值。以下哪一项是正确的?(GATE-CS-2005) (A) u = x + 10 和 v = y (B) u = x + 10 和 v != y (C) u + 10 = x 和 v = y (D) u + 10 = x 和 v != y
  • 预测以下程序的输出。
#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
fork() && fork() || fork();
fork();

printf("forkedn");
return 0;
}
 

最新文章

热点资讯

手游排行榜

CopyRight 2020-2030吾爱程序员

鄂ICP备2021004581号-8

本站资源收集于网络,如有侵权请联系我们:35492删除0109@qq.com