【问题标题】:CTRL+C and CTRL+Z signals won't block in CCTRL+C 和 CTRL+Z 信号不会在 C 中阻塞
【发布时间】:2016-03-14 18:57:16
【问题描述】:

我用 C 语言为一个简单的 3 人游戏编写了以下代码。

流程:

1) 询问用户中奖分数

2) 生成 3 个孩子

3) 每个都会​​产生随机分数并累加

4) 达到获胜分数的人获胜并终止程序。

void sigHandler(){}
void player(char *, int *, int *, int);
int main(int argc, char *argv[])
{
    int fd1[2], fd2[2], fd3[2], fd4[2], fd5[2], fd6[2], win;
    char turn='T';
    write(1, "This is a 3 player game with a Referee\n", 38);
    printf("Enter the winning score:\n");
    scanf("%d", &win);
    pipe(fd1);
    pipe(fd2);
    if(!fork())
        player("TOTO", fd1, fd2, win);
    sleep(1);
    close(fd1[0]);
    close(fd2[1]);

    pipe(fd3);
    pipe(fd4);
    if(!fork())
        player("TITI", fd3, fd4, win);
    sleep(1);
    close(fd3[0]);
    close(fd4[1]);

    pipe(fd5);
    pipe(fd6);
    if(!fork())
        player("TUTU", fd5, fd6, win);
    sleep(1);
    close(fd5[0]);
    close(fd6[1]);
    while(1)
    {
        signal(SIGINT, sigHandler);
        signal(SIGSTOP, sigHandler);
        write(1,"\nRefree: TOTO plays\n\n", 21);
        write(fd1[1], &turn, 1);
        read(fd2[0], &turn, 1);

        write(1,"\nRefree: TITI plays\n\n", 21);
        write(fd3[1], &turn, 1);
        read(fd4[0], &turn, 1);

        write(1,"\nRefree: TUTU plays\n\n", 21);
        write(fd5[1], &turn, 1);
        read(fd6[0], &turn, 1);
    }
}
void player(char *s, int *fd1, int *fd2, int win)
{
    int points=0, dice;
    char turn;
    srand(time(NULL));
    while(1)
    {
        signal(SIGINT, sigHandler);
        signal(SIGSTOP, sigHandler);
        read(fd1[0], &turn, 1);
        printf("%s: Playing my dice\n",s);
        dice =rand() % 20 + 1;
        printf("%s: got %d points\n", s, dice);
        points+=dice;
        printf("%s: Total so far %d\n\n", s, points);
        if(points>=win)
        {
            printf("%s: GAME OVER. I WON.\n", s);
            kill(0, SIGTERM);
        }
        sleep(3);
        write(fd2[1], &turn, 1);
    }
}

问题是我试图阻止 CTRL+ZCTRL+C 信号时程序正在执行,但当我使用以下代码块时它不起作用:

signal(SIGINT, sigHandler);
signal(SIGSTOP, sigHandler);

请提供一些建议。

【问题讨论】:

  • SIGSTOP 不能被抓到,也许你的意思是SIGTSTP。此外,您的信号处理程序的原型错误。你编译时启用了警告吗?
  • 是的,警告已启用。我收到未使用的参数 argc 和 argv[] 警告。
  • 啊抱歉,他们是正确的原型,当时缺乏咖啡。

标签: c unix pipe signals signal-handling


【解决方案1】:

使用预定义的SIG_IGN(忽略)比虚拟处理程序更好:

signal(SIGINT, SIG_IGN);   /* ignore Terminal interrupt signal */
signal(SIGTSTP, SIG_IGN);  /* ignore Terminal stop signal */

进一步阅读:

【讨论】:

    【解决方案2】:

    只是为了在@Thomas 的回答中添加一些内容,我将为您提供一个我自己认为在处理信号时有用的链接。

    https://www.usna.edu/Users/cs/aviv/classes/ic221/s16/lec/19/lec.html

    P.S:正如 Thomas 所说,使用 SIG_IGN 代替“虚拟”信号处理程序是一个非常简洁和经典的想法。

    【讨论】:

    • 您能否总结一下链接信息,以防该网站将来出现故障?
    猜你喜欢
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 2017-12-20
    • 2021-03-30
    • 2014-11-04
    相关资源
    最近更新 更多