Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix和信号处理程序(C)_C_Unix_Concurrency - Fatal编程技术网

Unix和信号处理程序(C)

Unix和信号处理程序(C),c,unix,concurrency,C,Unix,Concurrency,我是一名学生,我正在努力理解Unix编程课程中的信号 首先,我想测试一个简单的例子:一个进程生成一个子进程,需要对实际创建进行确认。 我用叉子叉着,在孩子的肚子里,我给父亲发了一个信号 kill(getppid(),SIGUSR1); 然后,在父亲的心里,我写了一个停顿();sys调用来阻止进程,直到收到信号,然后我编写了 (sigaction(SIGUSR1,&sa,NULL)检查 问题是,信号被发送,程序停止,没有处理程序执行 我用 $gcc -Wall -o test test.c 我没

我是一名学生,我正在努力理解Unix编程课程中的信号

首先,我想测试一个简单的例子:一个进程生成一个子进程,需要对实际创建进行确认。 我用叉子叉着,在孩子的肚子里,我给父亲发了一个信号 kill(getppid(),SIGUSR1); 然后,在父亲的心里,我写了一个停顿();sys调用来阻止进程,直到收到信号,然后我编写了 (sigaction(SIGUSR1,&sa,NULL)检查

问题是,信号被发送,程序停止,没有处理程序执行

我用

$gcc -Wall -o test test.c
我没有收到任何警告,输出是

$I am the father
$I am the child
$User defined signal 1
我知道我可以用其他的方法来实现这一点(使用sleepsys调用等),但我只想了解为什么这段代码不起作用

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void new_child (int sig){
    write(1,"I made a new child\n",50);
}

int main(){
    pid_t child;
    struct sigaction sa;            
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = new_child;
    switch(child = fork()){
        case -1:
            printf("Error.\n");
            exit(EXIT_FAILURE);
        case 0:
            printf("I am the child\n");
            kill(getppid(), SIGUSR1);
            break;
        default:
            printf("I am the father\n");
            pause();
            if (sigaction(SIGUSR1, &sa, NULL) == -1){
                printf("Signal error.\n");
                exit(EXIT_FAILURE);
            }
            printf("I'm done.");
            kill (child, SIGKILL);
            exit(EXIT_SUCCESS);
    }
}
#包括
#包括
#包括
#包括
无效新子项(int sig){
写(1,“我生了一个新孩子”,50);
}
int main(){
pid_t儿童;
struct-sigaction-sa;
sigemptyset(和sa.sa_面具);
sa.sa_标志=0;
sa.sa_handler=新的_子项;
开关(child=fork()){
案例1:
printf(“错误。\n”);
退出(退出失败);
案例0:
printf(“我是孩子”\n);
kill(getppid(),SIGUSR1);
打破
违约:
printf(“我是父亲”);
暂停();
if(sigaction(SIGUSR1,&sa,NULL)=-1){
printf(“信号错误。\n”);
退出(退出失败);
}
printf(“我做完了。”);
杀死(孩子,SIGKILL);
退出(退出成功);
}
}

我知道已经有人问过这个问题,但我似乎找不到一个适合我的解决方案。

您必须更改代码开头的信号,以便在收到SIGUSR后立即执行–Anjaneyulu


“必须在代码开头更改信号…”此限制有点严格。在调用
fork()
之前,需要安装最新的信号处理程序。
–alk

您必须更改代码开头的信号,以便在收到SIGUSR后立即执行。非常感谢。这确实有效!我发现sys call pause()非常有用,但我的书中甚至没有它的使用示例。
编写(1,“我生了一个新孩子”\n“,50);
将向文件描述符1写入大量垃圾,因为
的“我生了一个新孩子”
的长度远远小于50。这是技术上未定义的行为,可能会导致程序失败。@Anjaneyulu:“您必须更改代码开头的信号…”这个限制有点紧。在调用
fork()
@alk-yest信号处理程序而不是信号之前,需要安装最新的信号处理程序