考虑下面给出的代码:
#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
fork() && fork() || fork();
fork();
printf("forked\n");
return 0;
}
问题是forked
会被打印多少次。根据我的分析,它应该打印 20 次。另外this答案也证实了这一点。
但是当我在 onlinegdb.com 上运行代码时和 ideone.com ,他们分别打印了 18 次和 5 次。为什么会这样?
最佳答案
您的代码不会创建任何线程。这些线程称为 Pthreads在 Linux 上,您将使用 pthread_create(3) (内部使用 clone(2) )来创建它们。
当然,您的代码正在使用(错误地)fork(2)所以它创建了processes (除非 fork
失败)。请注意,fork
很难理解(也很难解释,所以我什至不会在这里尝试)。您可能需要阅读很多相关内容,例如fork维基页面,ALP ,也许Operating Systems: Three Easy Pieces (两者都有几个章节对其进行解释)。
您应该处理 fork
的失败。正如所解释的here ,每个 fork
需要考虑三种情况,并且您最好重写代码以最多执行一个 fork
每个语句(像pid_t pida = fork();
这样的赋值)
顺便说一句,您最好在每个 fork
之前刷新标准流(及其缓冲区中的数据)。 。我建议使用fflush(3)通过调用 fflush(NULL);
在每个 fork
之前.
请注意,每个进程都有自己的(唯一的)pid(请参阅 getpid(2) 和 credentials(7) )。如果将其打印出来,您可能会更好地理解,因此请尝试使用类似
printf("forked in %ld\n", (long) getpid());
的内容。
when I run the code
您确实应该在 Linux 下的计算机上运行该代码。考虑安装Linux distribution (也许在某些虚拟机中)在您的笔记本电脑或台式机上。请注意,Linux 对开发人员和学生非常友好,它主要由 free software 组成。您可以研究其源代码。
they print it 18 and 5 times respectively. Why so?
免费网络服务应该限制外部客户端使用的资源(在 Linux 上,他们可能会使用 setrlimit(2) 来达到此目的)。显然,此类网站(提供了运行几乎任意 C 代码的能力)希望避免 fork bombs 。很可能,您的一些fork
-s 对它们失败(并且由于您的原始代码不检查失败,因此您没有注意到)。
即使在您自己的桌面上,您也无法创建很多进程。根据经验,您的计算机上可能有数百个进程,其中大多数是 idle (等待,也许使用 poll(2) 或阻塞 read(2) 等,...对于某些 IO 或超时,另请参阅 time(7) ),并且只有十几个可以运行(通过 process scheduler 的你的 kernel )。换句话说,进程是相当昂贵的计算资源。如果您有太多可运行的进程,您可以尝试 thrashing .
使用ps(1)和 top(1) (以及 htop
和 pgrep(1) )来查询 Linux 系统上的进程。如果您想以编程方式执行此操作,请使用 /proc/
(更多信息请参阅 proc(5)) - 由 ps
使用, top
, pgrep
, htop
等等...
关于c - 给定的 C fork 代码将创建多少个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53968423/