c - 是否可以多次调用waitpid?[UNIX] [C]
问题描述
我的老师分配了一项工作,其中包括制作一个伪调度程序。我现在被困在最重要的部分。给我带来麻烦的行是最后的waitpid行。基本上我希望父进程等待他所有的孩子,这就是我这样做的原因。但是代码在那时冻结了。当我评论它时,它运行到最后,但没有写入 STDOUT。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#define LOOP_SIZE 20;
/* SIG HANDLERS DEFINITION */
void parentsighandler(int);
/* GLOBAL VARIABLE DEFINITION */
pid_t n, ppid;
int nb_args, compteur;
// array of pid_t to send signals to child
pid_t *child_pids;
int main(int argc, char *argv[]){
if (argc - 1 >= 1 ){
// Variable initialisation
compteur = 0;
nb_args = argc - 1;
child_pids = malloc((argc - 1) * sizeof(pid_t));
// String for sprintf
char sstr[40];
char rstr[40];
// Initializing all the pipes for the processes
int p[2 * (argc - 1)];
// getting the pid of the parent process
ppid = getpid();
//Initializing all pipes
int i, j, status, stop_val;
for (i = 0; i < argc - 1; i++){
if (pipe(&p[2*i]) == -1){
perror("pipe failed");
_exit(EXIT_FAILURE);
}
}
for (i = 0; i < argc - 1; i ++){
switch( n = fork()){
case -1:
perror("fork failed");
_exit(EXIT_FAILURE);
case 0:
/* CHILD */
if (0 == (stop_val = atoi(argv[i+1]))){
perror("atoi failed");
_exit(EXIT_FAILURE);
}
close(p[i*2]);
for (j = 0; j < 20 ; j++){
write(STDOUT_FILENO, "here\n", 5);
if (j % stop_val == 0){
kill(ppid, SIGUSR1);
}
sprintf(sstr, "Je suis le proc %d : message %d\n", getpid(), i);
write(p[i * 2 + 1], sstr, 40);
}
close(p[i*2+1]);
_exit(EXIT_SUCCESS);
default:
/* PARENT - process scheduling */
child_pids[i] = n;
kill(n, SIGSTOP);
}
}
write(STDOUT_FILENO, "Debut de l'ordonnancement\n",26);
// Setting up the signal
signal(SIGUSR1, parentsighandler);
write(STDOUT_FILENO, "before wait\n",12);
// The parent as to wait for all child to finish
for (i = 0; i < argc - 1; i ++){
// write(STDOUT_FILENO, "beit\n",12);
printf("value of pid n%d is %d\n", i, child_pids[i]);
// waitpid(child_pids[i], &status, 0);
// close(p[i * 2 + 1]); // closing the write end of the pipe
}
write(STDOUT_FILENO, "cefore main\n",12);
char mystr[15];
sprintf(mystr, "compteur : %d\n", compteur);
write(STDOUT_FILENO, mystr, 15);
while(1){
write(STDOUT_FILENO, "refore main\n",12);
kill(child_pids[compteur], SIGCONT);
write(STDOUT_FILENO, "jefore main\n",12);
while(read(p[2 * compteur], rstr, 40) > 0){
write(STDOUT_FILENO, rstr, 40);
}
}
} else {
perror("Not enough args\n");
_exit(EXIT_FAILURE);
}
return 0;
}
void parentsighandler(int sig){
if (sig == SIGUSR1){
write(STDOUT_FILENO, "passe dans sig handler\n", 23);
kill(child_pids[compteur], SIGSTOP);
if (compteur == nb_args){
compteur = 0;
} else {
compteur ++;
}
}
}
解决方案
为什么父母(似乎)停止在指令:
waitpid(child_pids[i], &status, 0);
因为孩子正在杀死父母,在父母设置信号处理程序之前
推荐阅读
- c# - Coroutine 中的 if 语句是如何工作的?
- reactjs - React - onLoad 调用中未定义元素引用
- swift - 如何使用 DateFormatter() 格式化日期
- javascript - 图像仅在画布 Fabric JS 上选择时出现
- php - 有没有办法在循环中获取 $_POST 变量?
- javascript - 如何在 WebGrid 中查找单个复选框的选中状态
- css - 如何为不同的图像尺寸自动隐藏图像底部的固定尺寸
- android - 为什么我的 Flutter 应用在退出时会下拉到屏幕底部?
- python-3.x - 错误:只有整数、切片 (`:`)、省略号 (`...`)、numpy.newaxis (`None`) 和整数或布尔数组是有效索引
- azure - Azure 活动目录是否容易受到 DoS 或 DDOS 攻击