Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何一次最多分叉父进程的5个子进程?_C_Fork_Parent Child_Children - Fatal编程技术网

C 如何一次最多分叉父进程的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", "

我有下面的代码,我试图一次最多只允许运行5个孩子,但我不知道如何在孩子退出时减少孩子数

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中