C 如何一次最多分叉父进程的5个子进程?
我有下面的代码,我试图一次最多只允许运行5个孩子,但我不知道如何在孩子退出时减少孩子数C 如何一次最多分叉父进程的5个子进程?,c,fork,parent-child,children,C,Fork,Parent Child,Children,我有下面的代码,我试图一次最多只允许运行5个孩子,但我不知道如何在孩子退出时减少孩子数 struct { char *s1; char *s2; } s[] = { {"one", "oneB"}, {"two", "twoB"}, {"three", "thr4eeB"}, {"asdf", "3th43reeB"}, {"asdfasdf", "thr33eeB"}, {"asdfasdfasdf", "thdfdreeB"}, {"af3c3", "
struct {
char *s1;
char *s2;
} s[] = {
{"one", "oneB"},
{"two", "twoB"},
{"three", "thr4eeB"},
{"asdf", "3th43reeB"},
{"asdfasdf", "thr33eeB"},
{"asdfasdfasdf", "thdfdreeB"},
{"af3c3", "thrasdfeeB"},
{"fec33", "threfdeB"},
{NULL, NULL}
};
int main(int argc, char *argv[])
{
int i, im5, children = 0;
int pid = fork();
for (i = 0; s[i].s2; i++)
{
im5 = 0;
switch (pid)
{
case -1:
{
printf("Error\n");
exit(255);
}
case 0:
{
printf("%s -> %s\n", s[i].s1, s[i].s2);
if (i==5) im5 = 1;
printf("%d\n", im5);
sleep(i);
exit(1);
}
default:
{ // Here is where I need to sleep the parent until chilren < 5
// so where do i decrement children so that it gets modified in the parent process?
while(children > 5)
sleep(1);
children++;
pid = fork();
}
}
}
return 1;
}
struct{
char*s1;
char*s2;
}s[]={
{“一”,“一个”},
{“两个”,“两个”},
{“三”,“thr4eeB”},
{“asdf”,“3th43reeB”},
{“asdfasdf”,“thr33eeB”},
{“asdfasdfasdf”,“thdfdreb”},
{“af3c3”,“thrasdfeeB”},
{“fec33”,“threfdeB”},
{NULL,NULL}
};
int main(int argc,char*argv[])
{
int i,im5,子代=0;
int-pid=fork();
对于(i=0;s[i].s2;i++)
{
im5=0;
开关(pid)
{
案例1:
{
printf(“错误\n”);
出口(255);
}
案例0:
{
printf(“%s->%s\n”,s[i].s1,s[i].s2);
如果(i==5)im5=1;
printf(“%d\n”,im5);
睡眠(i);
出口(1);
}
违约:
{//这里是我需要和父母睡觉的地方,直到孩子<5岁
//那么,我应该在哪里减少子进程,以便在父进程中修改它呢?
而(5岁以上儿童)
睡眠(1);
儿童++;
pid=fork();
}
}
}
返回1;
}
修订版似乎是基于评论而起作用的
struct{
char*s1;
char*s2;
}s[]={
{“一”,“一个”},
{“两个”,“两个”},
{“三”,“thr4eeB”},
{“asdf”,“3th43reeB”},
{“asdfasdf”,“thr33eeB”},
{“asdfasdfasdf”,“thdfdreb”},
{“af3c3”,“thrasdfeeB”},
{“fec33”,“threfdeB”},
{NULL,NULL}
};
pthread_mutex_t children_count_lock;
int儿童=0;
int main(int argc,char*argv[])
{
inti,im5;
int-pid=fork();
对于(i=0;s[i].s2;i++)
{
im5=0;
开关(pid)
{
案例1:
{
printf(“错误\n”);
出口(255);
}
案例0:
{
printf(“%s->%s\n”,s[i].s1,s[i].s2);
如果(i==5)im5=1;
printf(“%d\n”,im5);
睡眠(i);
pthread\u mutex\u lock(&children\u count\u lock);
儿童=儿童-1;
如果(儿童<0)儿童=0;
pthread_mutex_unlock(&children_count_lock);
出口(1);
}
违约:
{
如果(儿童>4)
等待();
pthread\u mutex\u lock(&children\u count\u lock);
儿童++;
pthread_mutex_unlock(&children_count_lock);
pid=fork();
}
}
}
返回1;
}
函数的wait()
系列将暂停父进程,直到子进程退出(这样做而不是休眠)
不,您根本不需要关键部分-孩子和家长不共享内存。在您的默认情况下,您的所有需求都是这样的:
default:
{
children++; // Last fork() was successful
while (children >= 5)
{
int status;
// Wait for one child to exit
if (wait(&status) == 0)
{
children--;
}
}
pid = fork();
}
(忘记我之前说过的将children
初始化为1,我没有注意到children++
应该在while循环之前)。函数族将挂起父进程,直到子进程退出(这样做而不是休眠)
不,您根本不需要关键部分-孩子和家长不共享内存。在您的默认情况下,您的所有需求都是这样的:
default:
{
children++; // Last fork() was successful
while (children >= 5)
{
int status;
// Wait for one child to exit
if (wait(&status) == 0)
{
children--;
}
}
pid = fork();
}
(忘记我之前说过的将
children
初始化为1,我没有注意到children++
应该在while循环之前)。一旦运行了最初的5个子进程,您可能希望使用wait()
等待子进程完成,此时您可以启动一个新的子进程。一旦您运行了最初的5个子进程,您可能希望使用wait()
等待子进程完成,此时您可以启动一个新的子进程。在父进程中调用wait()
。这将一直阻止,直到其中一个子项退出。在父项中调用wait()
。这将一直阻止,直到其中一个子项退出。因此,如果(children>5){wait();children--;}?@bstullkid--多处理很棘手--如果没有要等待的子项,wait将返回。如果您有两个孩子在等待时退出,您将不会注意到第二个出口。我认为您需要通过子对象上的共享内存来处理递减,因此需要互斥。不,wait()
不会错过子对象退出。子进程一直处于Z(僵尸)状态,直到它们的父进程wait()
s等待它们,正是出于这个原因。@caf--hmm。我的内存一定在运行。显然,如果wait没有错过一个退出的子项(并且假设您没有任何其他可能导致它提前返回的信号),这显然是正确的做法。您可以将您的wait
调用放入SIGCHLD
的信号处理程序中,并将您的计数保存在volatile sig\u atomic\t
(这是一个int
,平台可以在一条指令中加载或存储)。然后,您需要一个类似于临界段(block SIGCHLD)的东西来增加主代码中的计数,但您可以像普通变量一样从主代码中读取它,并从信号处理程序中读取/写入它。因此,我只需要执行if(children>5){wait();children--;}?@bstullkid--多处理很棘手--如果没有要等待的子对象,wait将简单地返回。如果在等待过程中有两个子对象退出,则不会注意到第二个退出。我认为您需要通过子对象上的共享内存处理减量--因此需要互斥对象。不,wait()
不会错过退出的子进程。子进程一直保持Z(僵尸)状态,直到它们的父进程wait()
s为它们等待,正是因为这个原因。@caf--hmmm。我的内存必须在运行。显然,如果wait没有错过退出的子进程(并且假设没有任何其他可能导致它提前返回的信号),这显然是要走的路。您可以将您的等待
呼叫放在s中