免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6400 | 回复: 4
打印 上一主题 下一主题

[C] 求助,sigwait和sigwaitinfo在linux下有不同的表现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-25 22:38 |只看该作者 |倒序浏览
sigwaitinfo在调用setgid后会跳出来,返回Interrupted system call,很诡异,但是sigwait就不会。


请看代码:

test2.c
  
  1. #include <signal.h>
  2. #include <errno.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>

  6. void sig_handler(int signum)
  7. {
  8.     printf("Receive signal. %d\n", signum);
  9. }

  10. void* sigmgr_thread()
  11. {
  12.     sigset_t   waitset, oset;
  13.     int        sig;
  14.     int        rc;
  15.     pthread_t  ppid = pthread_self();

  16.     pthread_detach(ppid);

  17.     sigemptyset(&waitset);
  18.     sigaddset(&waitset, SIGRTMIN);
  19.     sigaddset(&waitset, SIGRTMIN+2);
  20.     sigaddset(&waitset, SIGRTMAX);
  21.     sigaddset(&waitset, SIGUSR1);
  22.     sigaddset(&waitset, SIGUSR2);
  23.     siginfo_t myinfo;
  24.     while (1)  {
  25.         rc = sigwaitinfo(&waitset, &myinfo);
  26.         if (rc != -1) {
  27.             sig_handler(myinfo.si_signo);
  28.         } else {
  29.             printf("sigwaitinfo() returned err: %d; %s\n", errno, strerror(errno));
  30.         }
  31.     }
  32. }


  33. int main()
  34. {
  35.     sigset_t bset, oset;
  36.     int             i;
  37.     pid_t           pid = getpid();
  38.     pthread_t       ppid;

  39.     sigemptyset(&bset);
  40.     sigaddset(&bset, SIGRTMIN);
  41.     sigaddset(&bset, SIGRTMIN+2);
  42.     sigaddset(&bset, SIGRTMAX);
  43.     sigaddset(&bset, SIGUSR1);
  44.     sigaddset(&bset, SIGUSR2);

  45.     if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0)
  46.         printf("!! Set pthread mask failed\n");

  47.     kill(pid, SIGRTMAX);
  48.     kill(pid, SIGRTMAX);
  49.     kill(pid, SIGRTMIN+2);
  50.     kill(pid, SIGRTMIN);
  51.     kill(pid, SIGRTMIN+2);
  52.     kill(pid, SIGRTMIN);
  53.     kill(pid, SIGUSR2);
  54.     kill(pid, SIGUSR2);
  55.     kill(pid, SIGUSR1);
  56.     kill(pid, SIGUSR1);

  57.     // Create the dedicated thread sigmgr_thread() which will handle signals synchronously
  58.     pthread_create(&ppid, NULL, sigmgr_thread, NULL);
  59. //  pthread_detach(ppid);
  60.    sleep(1);
  61.     setgid(1001);
  62. sleep(1);   
  63. exit (0);
  64. }
复制代码

执行的结果是:
Receive signal. 10
Receive signal. 12
Receive signal. 34
Receive signal. 34
Receive signal. 36
Receive signal. 36
Receive signal. 64
Receive signal. 64
sigwaitinfo() returned err: 4; Interrupted system call



test.c
  1. #include <signal.h>
  2. #include <errno.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>

  6. void sig_handler(int signum)
  7. {
  8.     printf("Receive signal. %d\n", signum);
  9. }

  10. void* sigmgr_thread()
  11. {
  12.     sigset_t   waitset, oset;
  13.     int        sig;
  14.     int        rc;
  15.     pthread_t  ppid = pthread_self();

  16.     pthread_detach(ppid);

  17.     sigemptyset(&waitset);
  18.     sigaddset(&waitset, SIGRTMIN);
  19.     sigaddset(&waitset, SIGRTMIN+2);
  20.     sigaddset(&waitset, SIGRTMAX);
  21.     sigaddset(&waitset, SIGUSR1);
  22.     sigaddset(&waitset, SIGUSR2);
  23.         siginfo_t myinfo;
  24.     while (1)  {
  25.         rc = sigwait(&waitset, &sig);
  26.         if (rc != -1) {
  27.             sig_handler(sig);
  28.         } else {
  29.             printf("sigwaitinfo() returned err: %d; %s\n", errno, strerror(errno));
  30.         }
  31.     }
  32. }


  33. int main()
  34. {
  35.     sigset_t bset, oset;
  36.     int             i;
  37.     pid_t           pid = getpid();
  38.     pthread_t       ppid;

  39.     sigemptyset(&bset);
  40.     sigaddset(&bset, SIGRTMIN);
  41.     sigaddset(&bset, SIGRTMIN+2);
  42.     sigaddset(&bset, SIGRTMAX);
  43.     sigaddset(&bset, SIGUSR1);
  44.     sigaddset(&bset, SIGUSR2);

  45.     if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0)
  46.         printf("!! Set pthread mask failed\n");

  47.     kill(pid, SIGRTMAX);
  48.     kill(pid, SIGRTMAX);
  49.     kill(pid, SIGRTMIN+2);
  50.     kill(pid, SIGRTMIN);
  51.     kill(pid, SIGRTMIN+2);
  52.     kill(pid, SIGRTMIN);
  53.     kill(pid, SIGUSR2);
  54.     kill(pid, SIGUSR2);
  55.     kill(pid, SIGUSR1);
  56. kill(pid, SIGUSR1);

  57.     // Create the dedicated thread sigmgr_thread() which will handle signals synchronously
  58.     pthread_create(&ppid, NULL, sigmgr_thread, NULL);

  59.     sleep(1);
  60.     setgid(1001);
  61.     sleep(1);
  62.     exit (0);
  63. }
复制代码


执行结果是:
Receive signal. 10
Receive signal. 12
Receive signal. 34
Receive signal. 34
Receive signal. 36
Receive signal. 36
Receive signal. 64
Receive signal. 64


另外test2.c在freebsd下执行的结果是:
Receive signal. 30
Receive signal. 31
Receive signal. 65
Receive signal. 67
Receive signal. 126

难道在freebsd下实时信号不排队吗?


系统版本信息:

Linux skeeter-desktop 2.6.28-16-generic #56-Ubuntu SMP Mon Nov 2 10:43:06 UTC 2009 i686 GNU/Linux

FreeBSD  7.0-RELEASE FreeBSD 7.0-RELEASE #0: Sun Feb 24 19:59:52 UTC 2008     root@logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386



在linux下strace的结果是:
rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 USR2 RT_2 RT_4], = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, = 0
rt_sigprocmask(SIG_SETMASK, [USR1 USR2 RT_2 RT_4], NULL, = 0
nanosleep({1, 0}, {1, 0})               = 0
tgkill(14156, 14157, SIGRT_1)           = 0
sigwaitinfo() returned err: 4; Interrupted system call
setgid32(1001)                          = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 USR2 RT_2 RT_4], = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, = 0
rt_sigprocmask(SIG_SETMASK, [USR1 USR2 RT_2 RT_4], NULL, = 0
nanosleep({1, 0}, {1, 0})               = 0
exit_group(0)                           = ?

应该是这里的tgkill引起的,但我不知道SIGRT_1是啥,从字面上猜测SIGRT_1可能是第一个实时信号?但是为啥调用setgid会产生实时信号呢?

[ 本帖最后由 wwdwwd 于 2009-11-25 22:40 编辑 ]

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
2 [报告]
发表于 2009-11-25 23:12 |只看该作者
NPTL实现的时候用了实现信号的前两个 可能和这个有关系

论坛徽章:
0
3 [报告]
发表于 2009-11-26 00:14 |只看该作者
原帖由 vbs100 于 2009-11-25 23:12 发表
NPTL实现的时候用了实现信号的前两个 可能和这个有关系

哥们,能否详细的解说一下?我查了很多资料都查不出原因,thanks

论坛徽章:
0
4 [报告]
发表于 2009-11-26 15:40 |只看该作者
顶一下,继续求教

论坛徽章:
0
5 [报告]
发表于 2009-11-26 20:03 |只看该作者
我发现在solaris下面也不出错,那有可能就是linux实现的bug了。另外solaris下面实时信号也不排队,运行结果如下:
Receive signal. 16
Receive signal. 17
Receive signal. 41
Receive signal. 43
Receive signal. 48

比较奇怪
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP