如果在使用管道时子进程的数量大于处理器,进程会被阻塞吗?
Posted
技术标签:
【中文标题】如果在使用管道时子进程的数量大于处理器,进程会被阻塞吗?【英文标题】:Will processes be blocked, if the number of child processes greater than processors while using pipeline? 【发布时间】:2022-01-05 18:35:07 【问题描述】:当子进程的数量很大时,我的程序停止运行。我不知道问题可能是什么,但我猜想子进程在运行时被阻塞了。
这是程序的主要工作流程:
void function(int process_num)
int i;
// initial variables for fork()
int status = 0;
pid_t child_pid[process_num], wpid;
int *fds = malloc(sizeof(int) * process_num * 2);
// initial pipes
for(i=0; i<process_num; i++)
if(pipe(fds + i*2) <0)
exit(0);
// start child processes to write
for(i=0; i<process_num; i++)
child_pid[i] =fork();
if(child_pid[i] == 0)
close(fds[i*2]);
// do something ...
// write(fds[i*2+1], something);
close(fds[i*2+1]);
exit(0);
else if(child_pid[i] == -1)
printf("fork error\n");
exit(0);
// parent waits child processes and reads
for(i=0; i<process_num; i++)
pid_t cpid = waitpid(child_pid[i], &status, 0);
if (WIFEXITED(status))
close(fds[i*2+1]);
// do something ...
// read(fds[i*2], something);
close(fds[i*2]);
free(fds);
while((wpid = wait(&status)) > 0);
我通过 htop 检查了进程的状态,有几个(例如,8 个,而 process_num 为 110)子进程的状态为 S
。
现在我的问题来了:如果子进程的数量大于处理器的数量,在使用管道为子进程和当前进程进行通信时,子进程是否会被阻塞(父进程等待所有子进程执行) ?非常感谢!
编辑:我在使用read()
和write()
时打印了fds的Id,我发现读从4开始,写在5,我不知道为什么是案例,有人知道吗?
【问题讨论】:
不,处理器的数量不限制这个。您可以在单核机器上拥有(例如)100 个进程——没问题。更有可能的是,阻塞是由于您的代码中的错误造成的。具体来说,parent 进程应该在 进行任何等待之前关闭管道中间部分的 fd。我运行了您发布的程序,它在几分之一秒内完成,那么您发布的代码与您的实际程序有多接近? 你肯定有错误。当我将进程数设置为一个较小的数字(例如)10 但将缓冲区写入长度设置为 100,000 时,我被阻止了。read
电话在哪里?在每个阶段i
,您必须从fds[(i - 1) * 2]
读取并写入fds[i * 2 + 1]
。第一阶段是特殊的(例如)从某个文件中读取。而且,最后一个阶段是特殊的(例如)写入标准输出。我会使用struct
来控制每个阶段。有关 [在自定义外壳中] 工作管道的示例,请参阅我的回答:***.com/questions/52823093/fd-leak-custom-shell/…
@Craig Estey 嘿,非常感谢!我发现确实存在 read() 的错误。我的读取函数对其中一个数据长度为 0 的 fd 抛出错误。读取时fds[(i - 1) * 2]
是正确的,而不是fds[i*2]
?但是当i =0
时会发生什么?
就像我说的,第一阶段(即i == 0
)很特别。 i - 1
有 no [有效] fds
条目。并且,最后阶段同样没有有效的输出值。你正在做的是相当于一个shell pipe:| cat | cat | cat |
而不是cat < infile | cat | cat > outfile
@CraigEstey 哦,对不起,我不小心跳过了你提到的关于 i == 0 的部分。但我阅读了tldp.org/LDP/lpg/node11.html,并按照示例,i*2 用于阅读,i*2 + 1 写作
【参考方案1】:
处理器的数量在这里没有影响。操作系统是活的,能够运行任何有事可做的进程。 这是一个纯软件问题,所有进程都处于睡眠状态 (S) 等待某个永远不会发生的事件。
【讨论】:
以上是关于如果在使用管道时子进程的数量大于处理器,进程会被阻塞吗?的主要内容,如果未能解决你的问题,请参考以下文章