免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2457 | 回复: 5

[其他] 为什么父进程在为子进程改变进程组ID时,子进程收到了SIGHUP信号昵? [复制链接]

论坛徽章:
0
发表于 2012-11-09 11:27 |显示全部楼层
本帖最后由 DIYBYPERL 于 2012-11-09 12:51 编辑
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <signal.h>
  6. #include <errno.h>

  7. void signHand(int sign)
  8. {
  9.     printf("pid[%d]sign[%d] received----YHB\n", getpid(), sign);

  10.     if (sign == SIGHUP )
  11.     {      
  12.         printf("register SIGTTIN\n");
  13.         if( signal(SIGTTIN, signHand) == SIG_ERR)
  14.         {      
  15.             printf("Cant register SIG\n");
  16.         }      
  17.     }
  18.     //if (sign == SIGCONT )
  19.     //{     
  20.     //    printf("register SIGCONT\n");
  21.     //    if( signal(SIGCONT, signHand) == SIG_ERR)
  22.     //    {
  23.     //        printf("Cant register SIG\n");
  24.     //    }
  25.     //}
  26. }
  27. int main()
  28. {
  29.     setbuf(stdout,NULL);
  30.     printf("main: %d %d\n", getpid(), getpgrp());
  31.     pid_t pid = fork();
  32.     if(pid <0){
  33.         perror("fork");
  34.         return 1;
  35.     }

  36.     setpgid(pid,0);
  37.     if(pid >0){
  38.         printf("parent begin to 10 seconds\n");
  39.         sleep(10);
  40.         printf("parent let child come back\n");
  41. //------------>为什么父进程在为子进程改变进程组ID时,子进程收到了SIGHUP信号昵?
  42.         printf("setpgid[%d][%d][%s]\n", setpgid(pid, getpgrp()), errno, strerror(errno));
  43.         printf("parent begin to 20 seconds\n");
  44.         sleep(20);
  45.         printf("parent let child continue\n");
  46.         kill(pid, SIGCONT);
  47.         printf("parent wait child\n");
  48.         waitpid(pid,NULL,0);
  49.         printf("parent exit\n");
  50.         return 0;
  51.     }

  52.    char buf[1024];
  53.    printf("child: %d %d\n", getpid(), getpgrp());
  54.    if (signal(SIGHUP, signHand) == SIG_ERR)
  55.    {
  56.        printf("Cant register SIG\n");
  57.        return -1;
  58.    }
  59.    if (signal(SIGCONT, signHand) == SIG_ERR)
  60.    {
  61.        printf("Cant register SIG\n");
  62.        return -1;
  63.    }
  64.    while(fgets(buf,1024, stdin)){
  65.         printf("child.PID[%d].PGID[%d]>", getpid(), getpgrp());
  66.         fputs(buf, stdout);
  67.    }
  68.    printf("child exit\n");
  69.    return 0;
  70. }
复制代码
编译后的文件为a
  1. test:/home/test/testc>a
  2. main: 30671002 30671002
  3. child: 13369572 13369572
  4. parent begin to 10 seconds
  5. parent let child come back
  6. setpgid[0][0][Error 0]
  7. parent begin to 20 seconds
  8. pid[13369572]sign[19] received----test
  9. pid[13369572]sign[1] received----test
  10. register SIGTTIN
  11. 12345555555555555555555555555555
  12. child.PID[13369572].PGID[30671002]>12345555555555555555555555555555
  13. parent let child continue
  14. parent wait child
  15. 44444444444444444444444444444444444
  16. child.PID[13369572].PGID[30671002]>44444444444444444444444444444444444
  17. child exit
  18. parent exit
  19. test:/home/test/testc>
复制代码
请大侠解释下。。。。。。。。。。。。。。
环境是AIX 6.1

论坛徽章:
0
发表于 2012-11-09 16:14 |显示全部楼层
不能沉的。。。。。。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-11-10 12:38 |显示全部楼层
楼主AIX很神奇, 我表示怎么分析也分析不出来有理由SIGHUP, 因为子进程不在孤儿进程组里.

简单的注释了一下, 楼主再分析分析, 看有什么区别, 反正linux下是和楼主的结果不同:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <signal.h>
  6. #include <errno.h>
  7. #include <string.h>

  8. void signHand(int sign)
  9. {
  10.     printf("pid[%d]sign[%d] received----YHB\n", getpid(), sign);

  11.     if (sign == SIGHUP )
  12.     {      
  13.         printf("register SIGTTIN\n");

  14.         if( signal(SIGTTIN, signHand) == SIG_ERR)
  15.         {      
  16.             printf("Cant register SIG\n");
  17.         }      
  18.     }
  19. }

  20. int main()
  21. {
  22.     setbuf(stdout,NULL);
  23.     printf("main: %d %d\n", getpid(), getpgrp());
  24.    
  25.     pid_t pid = fork();
  26.    
  27.     if(pid < 0) {
  28.         perror("fork");
  29.         return 1;
  30.     }

  31.     //父进程将子进程的组设置为子进程的pid, 也就是子进程新进入了一个进程组
  32.     //子进程执行这句毫无效果, 虽然和父进程执行有竞争, 但没有实际效果, 想到于setpgid(0, 0);
  33.     setpgid(pid, 0);
  34.     printf("pid=%d gid=%d cccc", getpid(), getpgrp());

  35.     if(pid >0) {
  36.         printf("parent begin to 10 seconds\n");
  37.         sleep(2);
  38.         printf("parent let child come back\n");
  39.         //父进程又把子进程恢复到父进程的进程组里
  40.         //但你要知道子进程此刻一定是进程组长, 一个进程组长离开了进程组而已, 并且父进程组也不是孤儿组, 没理由SIGHUP啊
  41.         printf("setpgid[%d][%d][%s]\n", setpgid(pid, getpgrp()), errno, strerror(errno));
  42.         printf("parent begin to 20 seconds\n");
  43.         sleep(2);
  44.         printf("parent let child continue\n");
  45.         kill(pid, SIGCONT);
  46.         printf("parent wait child\n");
  47.         waitpid(pid,NULL,0);
  48.         printf("parent exit\n");
  49.         return 0;
  50.     }

  51.    char buf[1024];
  52.    printf("child: %d %d\n", getpid(), getpgrp());
  53.    if (signal(SIGHUP, signHand) == SIG_ERR)
  54.    {
  55.        printf("Cant register SIG\n");
  56.        return -1;
  57.    }
  58.    if (signal(SIGCONT, signHand) == SIG_ERR)
  59.    {
  60.        printf("Cant register SIG\n");
  61.        return -1;
  62.    }
  63.    //这里你可以看到, 子进程的确又回到了父进程的组
  64.    while(fgets(buf,1024, stdin)){
  65.         printf("child.PID[%d].PGID[%d]>", getpid(), getpgrp());
  66.         fputs(buf, stdout);
  67.    }
  68.    printf("child exit\n");
  69.    return 0;
  70. }
复制代码

论坛徽章:
0
发表于 2012-11-12 09:20 |显示全部楼层
回复 3# linux_c_py_php
能把你执行的结果贴出来看看么?

我在AIX 执行了你的代码,还是收到了SIGHUP信号:
  1. main: 28377192 28377192
  2. pid=39452678 gid=39452678 ccccchild: 39452678 39452678
  3. pid=28377192 gid=28377192 ccccparent begin to 10 seconds
  4. parent let child come back
  5. setpgid[0][0][Error 0]
  6. parent begin to 20 seconds
  7. pid[39452678]sign[19] received----YHB
  8. pid[39452678]sign[1] received----YHB
  9. register SIGTTIN
  10. parent let child continue
  11. parent wait child
  12. dasfdf
  13. child.PID[39452678].PGID[28377192]>dasfdf
  14. dsafdf
  15. child.PID[39452678].PGID[28377192]>dsafdf
  16. dafds
  17. child.PID[39452678].PGID[28377192]>dafds

  18. child.PID[39452678].PGID[28377192]>
  19. child exit
  20. parent exit
复制代码

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-11-12 11:03 |显示全部楼层
[root@vps616 c]# ./main
main: 27444 27444
pid=27444 gid=27444 ccccparent begin to 10 seconds
pid=27445 gid=27445 ccccchild: 27445 27445
parent let child come back
setpgid[0][0][Success]
parent begin to 20 seconds
parent let child continue
parent wait child
pid[27445]sign[18] received----YHB

论坛徽章:
0
发表于 2012-11-12 12:52 |显示全部楼层
回复 5# linux_c_py_php

pid[27445]sign[18] received----YHB
18是LINUX下的SIGCONT信号吧?

奇怪的AIX!!!
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP