在过去几天我写的一个程序遇到了一些困难。我只是想让一个程序与信号一起运行。当用户点击控件c时,我创建了两个管道和一个有两个子节点的父节点。
当用户从子进程中命中控件Z时,我希望孩子们彼此交谈。目前,我只是希望它打印出一些到终端的线路。在对问题进行一些测试之后,我总结了一些因素。
有人能看到我出错的地方......它真的开始让我烦恼:/
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
pid_t forkA, forkB;
void handleSignal();
void controlC();
void controlZ();
int main ()
{
signal(SIGINT, handleSignal);
while(1);
}
void handleSignal (int signal)
{
if (signal == SIGINT)
{
write(1, "ContrlC \n", 11);
controlC();
}
else if (signal == SIGTSTP)
{
write(1, "CONTROLZ \n", 11);
controlZ();
}
else
{
write(2, "error \n", 8);
}
}
void controlC()
{
int firstPipe[2];
int secondPipe[2];
if (pipe(firstPipe) < 0)
{
write(1,"Error \n", 7);
}
else if (pipe(secondPipe) < 0)
{
write(1,"Error creating pipe 2 \n", 23);
}
else
{
write(1, "Pipe creations: DONE \n", 22);
}
//make child
forkA = fork();
if (forkA < 0)
{
write(2, "FORK ERROR. \n", 13);
}
else if (forkA == 0)
{
write(1, "CHILD 1 \n", 9);
close(firstPipe[0]); //close reading end of pipe 1
close(secondPipe[1]);//close writing end of pipe 2
sleep(5);
}
else
{
forkB = fork();
if (forkB < 0)
{
write(2, "FORK ERROR. \n", 12);
}
else if (forkB == 0)
{
signal(SIGTSTP, handleSignal);
write(1, "CHild 2 \n", 9);
close(firstPipe[1]); //close write end of pipe 1
close(secondPipe[0]); //close read end of pipe 2
sleep(5);
}
else
{
//signal(SIGTSTP, handleSignal);
signal(SIGCHLD, SIG_IGN);
write(1,"parent of both \n", 16);
wait();
}
}
}
void controlZ()
{
write(1, "woo z \n", 7);
}
答案 0 :(得分:1)
来自signal(7):
信号处理是每进程属性
因此,这意味着您必须在所有分叉进程中定义信号行为。否则ctrl + c将终止进程或ctrl + z将停止进程。您不必明确SIG_IGN SIGCHLD,因为这是SIGCHLD的默认行为。
在不相关的说明中:请不要使用write(2)将文本输出到终端。使用fprintf(3)。如果要输出到stdout和stderr以输出错误消息,请使用stdout作为第一个参数。这样你就不必担心计算要写的字符数量。
您的等待调用也是错误的,它需要一个int *参数或至少一个NULL参数。
答案 1 :(得分:0)
write(1, "ContrlC \n", 11);
和write(1, "CONTROLZ \n", 11);
肯定是错误的长度。
建议采用不同的方法来避免计算错误,例如
#define CONTORLC "ContrlC \n"
write(1, CONTORLC, sizeof(CONTORLC) - 1);
或
void write_string(int handle, const char *s) {
write(handle, s, strlen(s));
}
虽然这会通过避免访问数组边界之外的内存来处理生成的UB,但可能还会存在其他问题。
答案 2 :(得分:0)
信号处理程序应尽可能快地保留。此外,您应该查看question来处理signal(2)
和sigaction(2)
之间的区别。
您是否只是尝试使用USR1
和USR2
以便不破坏sigint / sigcont的语义?