c - 当孩子收到 sigstop 信号时读取函数的行为
问题描述
节目说明
这些程序会产生 n 个子进程,这些子进程在创建后立即暂停。之后,这些子进程轮流通过管道与父进程对话。
他们谈话的时间是固定的(例如:应该总共谈话 20 次,但当他们连续谈话 7 次时停止并进入下一个流程)
程序流程
- 分叉所有的孩子
- 在创建后立即暂停它们
- 通过发送信号唤醒他们
- 子级通过管道向父级写入(在固定的时间内),然后在向父级发送信号后立即停止/父级读取管道的内容并写入 STDOUT
- 当父母收到信号改变管道读取其他孩子和信号唤醒下面的孩子
问题
我面临的问题是,当是时候过渡到下一个进程以收听它时,即使我确实在子进程中的管道。阅读时我是否缺少关于 SIGSTOP 和 SIGCONT 的内容。
注意:我确实阅读了文档
程序
#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, wpid;
int nb_args, read_return;
// array of pid_t to send signals to child
pid_t *child_pids;
volatile sig_atomic_t status = 0;
volatile sig_atomic_t compteur = 0;
int main(int argc, char *argv[]){
write(STDERR_FILENO, "** Begining the program\n", 24); // debug
nb_args = argc - 1;
if (nb_args >= 1 ){
// Variable initialisation
child_pids= malloc(nb_args * sizeof(pid_t));
// String for sprintf
char sstr[40];
char rstr[40];
char pidstr[23];
char strichild[16];
char strloopchild[10];
// Initializing all the pipes for the processes
int p[2 * nb_args];
// getting the pid of the parent process
ppid = getpid();
sprintf(pidstr, "Pid of parent is : %d\n", ppid);
write(STDERR_FILENO, pidstr, 23); // debug
int i, j, stop_val;
//Initializing all pipes
write(STDERR_FILENO, "**Init pipes\n", 13); // debug
for (i = 0; i < nb_args; i++){
if (pipe(&p[2*i]) == -1){
perror("Error : pipe failed");
_exit(EXIT_FAILURE);
}
}
write(STDERR_FILENO, "**end init pipes\n", 17); // debug
write(STDERR_FILENO, "**Begin fork\n", 15); // debug
for (i = 0; i < nb_args; i ++){
switch( n = fork()){
case -1:
perror("Error : fork failed");
_exit(EXIT_FAILURE);
case 0:
/* CHILD */
sprintf(strichild, "**In child n%d\n", i); // debug
write(STDERR_FILENO, strichild, strlen(strichild)); // debug
if (0 == (stop_val = atoi(argv[i+1]))){
perror("atoi failed");
_exit(EXIT_FAILURE);
}
sprintf(strichild, "stop_val is : %d\n", stop_val); // debug
write(STDERR_FILENO, strichild, strlen(strichild)); // debug
close(p[i*2]);
for (j = 1; j <= 20 ; j++){
sprintf(strloopchild, "loop : %d\n", j); // debug
write(STDERR_FILENO, strloopchild , strlen(strloopchild)); // debug
if (j % stop_val == 0){
write(STDERR_FILENO, "I am paused\n", 15); // debug
if ( kill(ppid, SIGUSR1) == -1){
write(STDERR_FILENO, "Could not kill\n",15); // debug
}
write(STDERR_FILENO, "Sent a sigusr1\n",15); // debug
kill(getpid(), SIGSTOP);
}
write(STDERR_FILENO, "In child : ",11);
sprintf(sstr, "J ecris sur l'entree %d du pipe\n", i*2+1);
write(STDERR_FILENO, sstr, strlen(sstr));
sprintf(sstr, "Je suis le proc %d : message %d\n", getpid(), j);
write(STDERR_FILENO, sstr, 40); // debug
write(p[i * 2 + 1], sstr, 40);
sleep(1);
}
close(p[i*2+1]);
write(STDERR_FILENO, "**Exiting the child\n", 20); // debug
_exit(EXIT_SUCCESS);
default:
/* PARENT - process scheduling */
write(STDERR_FILENO, "**Parent - puting to sleep childs\n", 34); // debug
child_pids[i] = n;
kill(n, SIGSTOP);
// Setting up the signal
signal(SIGUSR1, parentsighandler);
}
}
write(STDOUT_FILENO, "Debut de l'ordonnancement\n",26);
char strpids[20];
for (i = 0; i < nb_args; i++){
sprintf(strpids, "id processus : %d\n", child_pids[i]);
write(STDOUT_FILENO, strpids, 20);
}
char mystr[17];
sprintf(mystr, "compteur : %d\n", compteur); // debug
write(STDOUT_FILENO, mystr, 17); // debug
kill(child_pids[compteur], SIGCONT);
while(1){
if (read(p[2 * compteur], rstr, 40) > 0) {
write(STDOUT_FILENO,"P : ",5);
write(STDOUT_FILENO, rstr, 40);
sprintf(mystr, "compt value: %d\n", compteur); // debug
write(STDOUT_FILENO, mystr, 17); // debug
} else {
write(STDERR_FILENO, "Erreur lecture\n", 15);
}
sleep(1);
}
} else {
perror("Error : Not enough args\n");
_exit(EXIT_FAILURE);
}
return 0;
}
void parentsighandler(int sig){
if (sig == SIGUSR1){
write(STDOUT_FILENO, "*************\n", 14);//debug
write(STDOUT_FILENO, "P : going into sig handler\n", 28); // debug
if (compteur == (nb_args - 1)){
compteur = 0;
} else {
compteur ++;
}
kill(child_pids[compteur], SIGCONT);
char strst[19];
sprintf(strst, "P : compteur : %d\n", compteur); // debug
write(STDOUT_FILENO, strst, 19); // debug
write(STDOUT_FILENO, "*************\n", 14);//debug
}
}
解决方案
推荐阅读
- node.js - Universal-cookie 制作私有路由
- java - 在边界内找到最近的邻居和自身
- python - 销毁 Tkinter 按钮
- ios - Swift - NSInternalInconsistencyException',原因:'请求第 (1) 节的行数超出范围
- android - Websocket 安全错误:未验证主机名
- angular - 无法启动连接:错误并且无法加载资源:SignalR 中的 net::ERR_SSL_PROTOCOL_ERROR
- python - 如何将相关图保存为png
- flutter - 我在 windows 的 android studio 中设置颤振时出错,我已经更新并拥有最新版本的颤振和 android studio
- docker - 如何使用 docker log 在每次匹配特定字符串后指定日志数?
- node.js - 干净退出 - 重新启动前等待更改?