给定的C fork代码将创建多少个线程

时间:2018-12-29 09:45:36

标签: c fork

请考虑以下代码:

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

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

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

1 个答案:

答案 0 :(得分:4)

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

当然,您的代码正在(错误地)使用fork(2),因此它会创建processes (除非fork失败)。请注意, fork难以理解(并且难以解释),并且难以解释(因此我什至不在这里尝试)。您可能需要阅读很多相关内容,例如fork Wikipage,ALP,甚至还有Operating Systems: Three Easy Pieces(都有几个章节对其进行解释)。

您应该处理fork的失败。如here所述,每种fork都需要考虑三种情况,您最好重写代码,使每个语句最多执行fork个(像pid_t pida = fork();

顺便说一句,最好在每个fork前刷新标准流(及其缓冲区中的数据)。我建议通过在每个fflush(NULL);之前调用fork来使用fflush(3)

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

之类的东西
  

运行代码时

您确实应该在Linux下的您的计算机上运行该代码。考虑在笔记本电脑或台式机上安装Linux distribution(可能在某些虚拟机中)。请注意,Linux非常适合开发人员和学生,并且主要由free software组成,您可以学习其源代码。

  

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

免费的Web服务应限制外部客户端使用的资源(在Linux上,它们可能会为此目的使用setrlimit(2))。显然,此类站点能够运行几乎任意的C代码,都希望避免使用fork bombs。很可能您的某些fork失败了(并且由于原始代码不检查失败,所以您没有注意到)。

即使在您自己的桌面上,您也无法创建很多进程。根据经验,您的计算机上可能有数百个进程,其中大多数进程为idle(正在等待,可能是poll(2)或阻塞的read(2)等,...有关某些IO或某些超时的信息,另请参见time(7)),并且其中只有十几个是可运行的(由process schedulerkernel来运行)。换句话说,过程是相当昂贵的计算资源。如果您有太多可运行的进程,则可以尝试thrashing

使用ps(1)top(1)(还有htoppgrep(1))来查询Linux系统上的进程。如果要通过编程方式执行此操作,请使用/proc/(并参见proc(5))-pstoppgrep,{{ 1}}等...