免费注册 查看新帖 |

Chinaunix

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

[求教]看apue遇到的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-15 15:13 |只看该作者 |倒序浏览
看信号这章时碰到的问题,下面是代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>

  4. void sig_quit(int singo)
  5. {
  6.         printf("caught SIGQUIT\n" );
  7.         return;
  8. }

  9. void sig_alrm (int signo )
  10. {
  11.         printf("caught SIGALRM\n" );
  12.         return ;
  13. }               /* -----  end of function sig_alrm  ----- */

  14. int main(int argc, char *argv[])
  15. {
  16.         sigset_t newmask, oldmask;

  17.         signal(SIGQUIT, sig_quit);
  18.         signal(SIGALRM, sig_alrm);
  19.         sigemptyset(&newmask);
  20.         sigaddset(&newmask, SIGQUIT);
  21.         sigprocmask(SIG_BLOCK, &newmask, &oldmask);

  22.         alarm(4);
  23.         sleep(10);

  24.         sigprocmask(0, NULL, &oldmask);
  25.         sigpending(&newmask);
  26.         if(sigismember(&newmask, SIGQUIT))
  27.                 printf("SIGQUIT pending.newmask=%u\n", newmask);

  28.         printf("oldmask=%u, newmask=%u\n", oldmask, newmask);
  29.         
  30.         if(sigismember(&newmask, SIGQUIT))
  31.                 printf("SIGQUIT pending.newmask=%u\n", newmask);
  32.         return 0;
  33. }
复制代码

执行:
$a.out
^\caught SIGALRM
SIGQUIT pending.newmask=4
oldmask=4, newmask=0     //为什么上下newmask都是4而中间的是0呢?
SIGQUIT pending.newmask=4
谢谢!

论坛徽章:
0
2 [报告]
发表于 2007-04-15 21:39 |只看该作者
我弄清楚了

sigset_t的结构为:
typedef struct __sigset {
    __uint32_t __bits[_SIG_WORDS];
} __sigset_t;

所以要用printf可以先转存到int里面去.
unsigned long int a,b;
a=*(oldmask.__bits);
b=*(newmask.__bits);
这样子输出就正常了.

一般32位系统的_SIG_WORDS被define为4也就是sigset_t为128位的,
但是printf里面的%u为32位的,也就是说存参的时候push进去了两个128位,而实际
printf只读了前64位(两个32位的unsigned int).所以printf的第二个输出为0,实
际上是因为sigset_t为128位.以下程序可以证明这一点:

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

int main(int argc, char *argv[])
{
    sigset_t newmask, oldmask;

    sigemptyset(&newmask);
    sigemptyset(&oldmask);
    sigaddset(&newmask, SIGQUIT);
    sigaddset(&oldmask, SIGILL);
    printf("%u,%u\n", oldmask, newmask);
    printf("%u,%u\n", newmask, oldmask);
    sigaddset(&oldmask, 33);
    printf("%u,%u\n", oldmask, newmask);
    printf("%u,%u\n", newmask, oldmask);
    return 0;
}
输出为:
8,0
4,0
8,1
4,0

sigaddset(&oldmask, 33)后第33位置1,导致printf的第二个%u为1.所以输出为8,1
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP