gpt4 book ai didi

c - 从管道读取信号发送

转载 作者:太空宇宙 更新时间:2023-11-04 08:41:15 25 4
gpt4 key购买 nike

我愿意:

父进程:

  • 将数据写入管道
  • 向子进程发送信号

子进程:

  • 捕捉到信号后读取数据。

这是我的试用版:

#include<stdio.h>
#include<string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>

int fd[2];


//Handler - Exiting process, OR reading from pipe
void sigHandler(int signumber){

if(signumber == SIGUSR1) {

printf("SIGUSR1 catched.\n");


//So lets read from pipe
int read_data = -1;
close(fd[1]);
read(fd[0], &read_data, sizeof(read_data));

//This printf never gets called
printf("Received data: %s", read_data);


}
else {

printf("SIGQUIT catched.\n");
exit(3);
}
}

//This is handles parent process to NOT exit on sending a signal
//maybe not the best workaround but i could only do this in this way.
void sigDummy(int signumber){
printf("SigDummy catched\n");
}


int main(){

fflush(stdout);

pipe(fd);
char option=-1;

pid_t child_a;
pid_t child_b;

child_a = fork();

//A Child Proc which is not used atm, it will be
if (child_a == 0) {

signal(SIGQUIT ,sigHandler);
signal(SIGUSR1 ,sigHandler);

while(1) {
//idle
sleep(1);
printf("child_a iddle work\n");

}


}

//Child B Proc for reading form the PIPE after got SIGUSR1 signal
else {
child_b = fork();

if (child_b == 0) {

signal(SIGQUIT ,sigHandler);
signal(SIGUSR1 ,sigHandler);

while(1) {
//idle
sleep(1);
printf("child_b iddle work\n");

}

}
//Parent Proc for writing to a pipe and sending signals to child B to read the pipe
else {

signal(SIGUSR1 ,sigDummy);

//MENU WHILE
while(option!=0){

scanf("%d", &option);
printf("input was: %d\n", option);
kill(child_b,SIGUSR1);

close(fd[0]);
write(fd[1], &option, sizeof(option));
}

}//End of Menu while

//Exiting child prcoesses then exiting parent prcoess
if(option==0){

int status_a, status_b;

waitpid(child_b, &status_b, WNOHANG|WUNTRACED);
waitpid(child_a, &status_a, WNOHANG|WUNTRACED);

kill(child_b,SIGQUIT);
kill(child_a,SIGQUIT);

}

}

return 1;

}

输出:

child_b iddle work
child_a iddle work
child_b iddle work
child_a iddle work
child_b iddle work
child_a iddle work
child_b iddle work
child_a iddle work
4
input was: 4
SigDummy catched
SIGUSR1 catched.
SIGUSR1 catched. //I wait here several seconds, child_a and b processes are not printing anything anymore....
3
input was: 3
SigDummy catched
1
input was: 1
SigDummy catched

如果我删除管道写入管道读取部分我有很好的工作代码:

没有管道写入和读取的输出:

child_a iddle work
child_b iddle work
3
input was: 3
SigDummy catched
SIGUSR1 catched.
child_a iddle work
SIGUSR1 catched.
child_b iddle work
child_a iddle work
child_b iddle work
2
input was: 2
SigDummy catched
SIGUSR1 catched.
child_b iddle work
SIGUSR1 catched.
child_a iddle work
child_b iddle work
child_a iddle work
1
input was: 1
SigDummy catched
SIGUSR1 catched.
child_b iddle work
SIGUSR1 catched.
child_a iddle work
child_b iddle work
child_a iddle work
4
input was: 4 //Inputs are always catched with my signal handler func, and child processes does not stop printing.
SigDummy catched
SIGUSR1 catched.
child_b iddle work
SIGUSR1 catched.
child_a iddle work
child_b iddle work
child_a iddle work
child_b iddle work
child_a iddle work
0
input was: 0
SigDummy catched
SIGUSR1 catched.
SIGQUIT catched.
SIGUSR1 catched.
SIGQUIT catched.
Exiting

我发现的方法在没有写-读管道部分的情况下运行良好。但是加了之后就是随机错了。

那么,为什么当我尝试执行管道发送操作时我的代码行为不同?刚开始学c,代码可能真的乱七八糟,还请多多包涵。

最佳答案

问题是 printf("Received data: %s", read_data); 语句。通过将 %s 放入格式字符串中,read_data 变量被视为指针并取消引用(您可能需要 %d 或类似的).

当您输入值 4 时。您最终尝试访问地址 0xffffff04,这通常会导致段错误,但在信号处理程序的上下文中,它似乎只是默默地杀死了子进程。

其他一些事情:

  • 您不应多次关闭文件。文件描述符编号可能会在别处重复使用,您甚至可能会无意中关闭一些您没有预料到的内容。

  • 注意您正在写入和读取的数据。您正在编写一个 char 大小的内存,但读入一个 int。确保这是您真正想要的,否则您会得到意想不到的值。

  • 通常,信号处理程序不适合做大量繁重的工作。许多操作在这里都不是很安全,并且会在程序以意外方式中断时干扰程序正在执行的操作。通常最好使用信号处理程序来简单地通知程序的其余部分需要注意某些事情,并让主程序完成大部分工作。

  • 在处理文件时,甚至比使用信号更好的是,您可以使用 poll() 或 select() 调用进行同步(或者如果您的代码足够简单,只需使用 read() 阻塞文件...您的示例代码被重构以完全删除信号处理程序并仍然以相同的方式工作,但您的实际代码可能比这更复杂)。

关于c - 从管道读取信号发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23456764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com