V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
RingoTC
V2EX  ›  问与答

有关 “Unix 信号不排队”的问题

  •  
  •   RingoTC · 2018-08-05 22:02:10 +08:00 · 2102 次点击
    这是一个创建于 2082 天前的主题,其中的信息可能已经有所发展或是发生改变。

    题目描述

    在《 CSAPP 》中有一个简单的 signal 示例程序。我在 Ubuntu 里编译运行相同的代码,得到的结果和书上给出的结果不一样,并且就是在最关键的一个地方不一样:信号不排队。

    1653775554-5b4cbf6d71972_articlex.jpg

    而我在自己的机器上编译运行结果:

    1427201528-5b4df14ca19ca_articlex.png

    按照书里面的说法,Handler reaped child 这一项应该只出现两次。

    相关代码

    #include "csapp.h"
    /* $begin signal1 */
    /* WARNING: This code is buggy! */
    
    void handler1(int sig) 
    {
        int olderrno = errno;
    
        if ((waitpid(-1, NULL, 0)) < 0)
            sio_error("waitpid error");
        Sio_puts("Handler reaped child\n");
        Sleep(1);
        errno = olderrno;
    }
    
    int main() 
    {
        int i, n;
        char buf[MAXBUF];
    
        if (signal(SIGCHLD, handler1) == SIG_ERR)
            unix_error("signal error");
    
        /* Parent creates children */
        for (i = 0; i < 3; i++) {
            if (Fork() == 0) {
                printf("Hello from child %d\n", (int)getpid());
                exit(0);
            }
        }
    
        /* Parent waits for terminal input and then processes it */
        if ((n = read(STDIN_FILENO, buf, sizeof(buf))) < 0)
            unix_error("read");
    
        printf("Parent processing input\n");
        while (1)
            ;
    
        exit(0);
    }
    /* $end signal1 */
    
    
    7 条回复    2018-08-06 13:12:15 +08:00
    redsonic
        1
    redsonic  
       2018-08-06 00:15:27 +08:00   ❤️ 1
    内核中的信号处理和进程调度有关联性,一般都是计时上的问题,我试了两台空闲的都和书上的一样,打印两次。然后生成子进程的时候延迟错开一下就打印三次了,exit 的时候不容易撞到。不必纠结,也许你系统繁忙 /空闲的时候结果会不一样,明白道理就行了。
    /* Parent creates children */
    for (i = 0; i < 3; i++) {
    usleep(100)
    if (Fork() == 0) {
    manifold
        2
    manifold  
       2018-08-06 02:19:35 +08:00 via Android
    这个本身就取决于进程调度(因为 signal 是在陷入内核是 handle 的)。。所以理论上可以出现各种情况。因此要用 waitpid 来回收 zombie processes
    ryd994
        3
    ryd994  
       2018-08-06 02:21:44 +08:00 via Android
    你是不是在虚拟机里,而且是单核虚拟机?
    RingoTC
        4
    RingoTC  
    OP
       2018-08-06 03:07:03 +08:00 via Android
    @ryd994 是在 wsl 里面
    ryd994
        5
    ryd994  
       2018-08-06 06:50:09 +08:00 via Android
    @RingoTC ………………
    你都没有在用 Linux 还有什么好说的呢?
    wsl 是 Windows 内核+syscall 翻译
    x86vk
        6
    x86vk  
       2018-08-06 08:07:22 +08:00 via Android
    @RingoTC wsl 还不能完全兼容 posix 规范,特别是线程,文件这种
    RingoTC
        7
    RingoTC  
    OP
       2018-08-06 13:12:15 +08:00 via Android
    @ryd994 好吧...一直以为 wsl 就是单纯的虚拟机,只是更方便而已....
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3669 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 10:38 · PVG 18:38 · LAX 03:38 · JFK 06:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.