通过fork()在C中创建多进程和模拟
我想创建多个进程组,它们将调用不同的函数 我在下面写代码。 首先,我想得到以下输出 /叉子4 5通过fork()在C中创建多进程和模拟,c,unix,C,Unix,我想创建多个进程组,它们将调用不同的函数 我在下面写代码。 首先,我想得到以下输出 /叉子4 5 I am a child: 1 PID: 22330 I am a child2: 1 PID: 22334 I am a child: 2 PID: 22331 I am a child2: 5 PID: 22338 I am a child: 4 PID: 22333 I am a child: 3 PID: 22332 I am a child2: 2 PID: 22335 I
I am a child: 1 PID: 22330
I am a child2: 1 PID: 22334
I am a child: 2 PID: 22331
I am a child2: 5 PID: 22338
I am a child: 4 PID: 22333
I am a child: 3 PID: 22332
I am a child2: 2 PID: 22335
I am a child2: 4 PID: 22337
I am a child2: 3 PID: 22336
"
如果这是您的问题,这意味着您的根进程比其子进程早退出。使用waitpid()[1]使根目录等待其子进程
[1]
LE:您将waitpid放在根进程而不是分叉进程中
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int forkChildren(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child: %d PID: %d\n",i, getpid());
sleep(5);
return 1;
}
}
return 0;
}
int forkChildren2(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child2: %d PID: %d\n", i, getpid());
sleep(2);
return 1;
}
}
return 0;
}
int main(int argc, char **argv) {
int ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
return EXIT_FAILURE;
}
ret = forkChildren(atoi(argv[1]));
if (ret == 0)
forkChildren2(atoi(argv[2]));
// wait(...) for all pids here, if you wish
return EXIT_SUCCESS;
}
LLE:好的,我终于得到了您想要做的事情,jweyrich观察得出了一个想法,它是这样的:返回子进程的PID数组,然后从根进程终止它们
主视图应如下所示:
int* child_pids
//mem allocation
forkChildren();
for each pid in child_pids
kill(pid,*signal termination*)
forkChildren2()
如果这是您的问题,这意味着您的根进程比其子进程早退出。使用waitpid()[1]使根目录等待其子进程
[1]
LE:您将waitpid放在根进程而不是分叉进程中
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int forkChildren(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child: %d PID: %d\n",i, getpid());
sleep(5);
return 1;
}
}
return 0;
}
int forkChildren2(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child2: %d PID: %d\n", i, getpid());
sleep(2);
return 1;
}
}
return 0;
}
int main(int argc, char **argv) {
int ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
return EXIT_FAILURE;
}
ret = forkChildren(atoi(argv[1]));
if (ret == 0)
forkChildren2(atoi(argv[2]));
// wait(...) for all pids here, if you wish
return EXIT_SUCCESS;
}
LLE:好的,我终于得到了您想要做的事情,jweyrich观察得出了一个想法,它是这样的:返回子进程的PID数组,然后从根进程终止它们
主视图应如下所示:
int* child_pids
//mem allocation
forkChildren();
for each pid in child_pids
kill(pid,*signal termination*)
forkChildren2()
根据您在@Cristina's answer上的评论,问题是它正在生成20个child2,而不是命令行参数中指定的5个。原因是由
forkChildren
创建的每个子进程都返回到main
并调用forkChildren2
。因为4(forkChildren)*5(forkChildren2)=20,加上父进程创建的5,所以得到了20(实际上是25)个child2
我将返回值添加到函数中(这两个函数都是为了保持它们的相似性),如果是子进程,则添加一个if
条件以跳过forkChildren2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int forkChildren(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child: %d PID: %d\n",i, getpid());
sleep(5);
return 1;
}
}
return 0;
}
int forkChildren2(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child2: %d PID: %d\n", i, getpid());
sleep(2);
return 1;
}
}
return 0;
}
int main(int argc, char **argv) {
int ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
return EXIT_FAILURE;
}
ret = forkChildren(atoi(argv[1]));
if (ret == 0)
forkChildren2(atoi(argv[2]));
// wait(...) for all pids here, if you wish
return EXIT_SUCCESS;
}
#包括
#包括
#包括
智力儿童(智力儿童){
int i;
pid_t pid;
对于(i=1;i根据您在@Cristina的回答中所做的评论,问题是它分叉了20个child2,而不是命令行参数中指定的5个。原因是由forkChildren
创建的每个子进程都返回到main
并调用forkChildren2
。您得到了20个(实际上是25个)child2因为4(forkChildren)*5(forkChildren2)=20,加上父进程创建的5
我将返回值添加到函数中(这两个函数都是为了保持它们的相似性),如果是子进程,则添加一个if
条件以跳过forkChildren2
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int forkChildren(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child: %d PID: %d\n",i, getpid());
sleep(5);
return 1;
}
}
return 0;
}
int forkChildren2(int nChildren) {
int i;
pid_t pid;
for (i = 1; i <= nChildren; i++) {
pid = fork();
if (pid == -1) {
/* error handling here, if needed */
return -1;
}
if (pid == 0) {
printf("I am a child2: %d PID: %d\n", i, getpid());
sleep(2);
return 1;
}
}
return 0;
}
int main(int argc, char **argv) {
int ret;
if (argc != 3) {
fprintf(stderr, "Usage: %s <nChild> <nChild2>\n", getprogname());
return EXIT_FAILURE;
}
ret = forkChildren(atoi(argv[1]));
if (ret == 0)
forkChildren2(atoi(argv[2]));
// wait(...) for all pids here, if you wish
return EXIT_SUCCESS;
}
#包括
#包括
#包括
智力儿童(智力儿童){
int i;
pid_t pid;
对于(i=1;我是否使用fflush(stdout)使打印更加有序?仍在尝试理解此处的问题。您的“问题”中缺少一些详细信息,例如主代码和问题所在。抱歉,我添加了缺少的代码。请更新您的问题,以提及您在下面的评论中描述的问题。是否使用fflush(stdout)使打印更有序?仍在试图理解此处的问题。您的“问题”中缺少一些详细信息,例如主代码和问题的原因。抱歉,我添加了缺少的代码。请更新您的问题,以提及您在下面的评论中描述的问题。我很困惑。我将把wait()fork()放在哪里将被调用两次,其中是根进程。我想得到4个child和5个child2它给了我20个child2这是因为所有child
都是从forkChildren
返回并运行forkChildren2
。因此得到4*5=20。您必须更改fork的方式,或者只在父进程。我很困惑。我将把wait()fork()放在哪里将被调用两次,其中是根进程。我想得到4个child和5个child2它给了我20个child2这是因为所有child
都是从forkChildren
返回并运行forkChildren2
。因此得到4*5=20。您必须更改fork的方式,或者只在父进程。谢谢你的帮助。它工作正常。如果我不想模拟孩子们。让他们以不同的顺序工作会怎么样。睡眠函数不能。我应该尝试使用信号量吗?你说的以不同的顺序工作是什么意思?线程是相互独立的。信号量用于同步。如果你给出一个好的描述,我可能会提供帮助说明你想做什么。事实上,我正在尝试编写多生产者单消费者模拟。在forkChildren中,会调用forkChildren2 cosume中的add_a()函数。如果我首先将此函数添加到由第一个fork的子函数数调用的wfunction中,然后使用由第二个fork的子函数数调用的函数。我想模拟类似的示例。(它的工作顺序可能不同)add_a()consumer_()add_a()add_a()add_a()consumer_a()谢谢,现在我明白了。你不必担心它们的执行顺序,但你需要信号量来通知消费者线程队列/列表/任何东西上有一个项目可用。每当生产者将一个项目放入容器时,它都会通知消费者唤醒并处理该项目。这样做可以避免处理器消耗循环。有关更多信息,请阅读“谢谢帮助”。它工作正常。如果我不想模拟孩子们,让他们以不同的顺序工作会怎么样。睡眠功能无法做到。我应该尝试使用信号量吗?你说的以不同的顺序工作是什么意思?线程是相互独立的。信号量用于同步。如果你愿意,我可能会提供帮助很好地描述一下你想要做什么。事实上,我正在尝试编写多生产者单消费者模拟。在forkChildren中,add_a()将在forkChildren2中被调用,cosume_a将被调用。如果我把这个函数放在第一位,添加一个由第一位的子函数的数量调用的wfunction