首页 > 解决方案 > 给定的 C fork 代码将创建多少个线程

问题描述

考虑下面给出的代码:

#include <stdio.h> 
#include <unistd.h> 
int main() 
{ 
   fork(); 
   fork() && fork() || fork(); 
   fork();
   printf("forked\n"); 
   return 0; 
}

forked问题是要打印多少次。根据我的分析,它应该打印 20 次。这个答案也证实了这一点。

但是,当我在onlinegdb.comideone.com上运行代码时,它们分别打印了 18 次和 5 次。为什么这样?

标签: cfork

解决方案


您的代码不会创建任何线程。这些在 Linux 上称为Pthreads,您将使用pthread_create(3)(内部使用clone(2))来创建它们。

当然,您的代码正在(错误地)使用fork(2),因此它创建了进程(除非fork失败)。请注意,这很难理解(fork很难解释,所以我什至不会在这里尝试)。你可能需要阅读很多关于它的内容,例如fork wikipage、ALP,也许还有操作系统:三个简单的部分(都有几个章节来解释它)。

您应该处理fork. 正如这里所解释的那样,每种情况需要考虑三种情况fork,您最好重写代码以使fork每个语句最多执行一个(类似的赋值pid_t pida = fork();

顺便说一句,您最好在每个fork. 我建议在 every 之前调用fflush(3)fflush(NULL);fork

请注意,每个进程都有自己的(唯一的)pid(参见getpid(2)credentials(7))。如果您打印它,您可能会更好地理解事情,所以尝试使用类似的东西
printf("forked in %ld\n", (long) getpid());

当我运行代码时

你真的应该你的计算机上运行 Linux 下的代码。考虑在笔记本电脑或台式机上安装Linux 发行版(可能在某些虚拟机中)。请注意,Linux 对开发人员和学生都非常友好,而且它主要由您可以学习其源代码的免费软件组成。

他们分别打印 18 次和 5 次。为什么这样?

免费的 Web 服务应该限制外部客户端使用的资源(在 Linux 上,他们可能会为此目的使用setrlimit(2) )。显然,这样的网站——能够运行几乎任意的 C 代码——想要避免分叉炸弹。很可能,您的一些fork-s 在它们上失败了(并且由于您的原始代码不检查失败,因此您没有注意到)。

即使在您自己的桌面上,您也无法创建很多进程。根据经验,您的计算机上可能有数百个进程,其中大多数处于空闲状态(等待,可能使用poll(2)或阻塞read(2)等,......对于某些 IO 或某些超时,另请参见time(7)),其中只有十几个可运行(由内核的进程调度程序。换句话说,进程是相当昂贵的计算资源。如果您有太多可运行的进程,您可以尝试thrashing

使用ps(1)top(1)htop以及pgrep(1))来查询 Linux 系统上的进程。如果您想以编程方式执行此操作,请使用/proc/(有关更多信息,请参见proc(5))- 由ps, top,pgrep等使用htop...


推荐阅读