免费注册 查看新帖 |

Chinaunix

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

[学习] APUE 270页的一个疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-15 21:33 |只看该作者 |倒序浏览
本帖最后由 你还未够水准呢 于 2012-11-15 21:34 编辑
  1. #include "apue.h"
  2. #define pr_mask printf

  3. static void sig_int(int);

  4. int main(void)
  5. {
  6.     sigset_t    newmask, oldmask, waitmask;

  7.     pr_mask("program start: \n");

  8.     if (signal(SIGINT, sig_int) == SIG_ERR)
  9.         err_sys("signal(SIGINT) error");
  10.     sigemptyset(&waitmask);
  11.     sigaddset(&waitmask, SIGUSR1);
  12.     sigemptyset(&newmask);
  13.     sigaddset(&newmask, SIGINT);

  14.     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
  15.         err_sys("SIG_BLOCK error");
  16.    
  17.     pr_mask("in critical region: \n");

  18.     if (sigsuspend(&waitmask) != -1)
  19.         err_sys("sigsuspend error");

  20.     pr_mask("after return from sigsuspend: \n");

  21.     //if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
  22.         //err_sys("SIG_SETMASK error");

  23.     pr_mask("program exit: \n");

  24.     exit(0);
  25. }

  26. static void sig_int(int signo)
  27. {
  28.     pr_mask("\nin sig_int: \n");
  29. }
复制代码
上面的代码我注释了两行

sigsuspend返回后进程中的屏蔽字是newmask 那应该屏蔽了 SIGINT啊
我在按下 Crtl+C 依然执行了  sig_int(int signo)  函数啊

不是阻塞了 SIGINT信号么

论坛徽章:
0
2 [报告]
发表于 2012-11-16 11:10 |只看该作者
主要原因是sigsuspend函数的作用:它使本进程的信号屏蔽字设置为waitmask所指向的信号值。你这里是sigusr1,所以不能屏蔽sigint信号了。你试试用其他信号试试吧。希望对你有用,我也是在看unix环境高级编程,一起学习哟!

论坛徽章:
0
3 [报告]
发表于 2012-11-16 11:21 |只看该作者
本帖最后由 你还未够水准呢 于 2012-11-16 11:22 编辑

但是sigsuspend返回后不是恢复了进程屏蔽字么

我这个注释了 貌似sigsuspend就没返回了。。。

我再添加个信号 让sigsuspend返回试一试

只为你飘的雪 发表于 2012-11-16 11:10
主要原因是sigsuspend函数的作用:它使本进程的信号屏蔽字设置为waitmask所指向的信号值。你这里是sigusr1, ...

论坛徽章:
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
4 [报告]
发表于 2012-11-16 11:51 |只看该作者
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #define pr_mask printf
  6. #define err_sys printf

  7. int n = 0;
  8. static void sig_int(int);

  9. int main(void)
  10. {
  11.         sigset_t newmask, oldmask, waitmask;

  12.         pr_mask("program start: \n");

  13.     //1, 锁信号(阻塞SIGINT, SIGUSR1)
  14.         sigemptyset(&waitmask);
  15.         sigaddset(&waitmask, SIGUSR1);
  16.         sigemptyset(&newmask);
  17.         sigaddset(&newmask, SIGINT);
  18.     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
  19.                 err_sys("SIG_BLOCK error");

  20.     //2, 注册处理函数. (1与2最好保持顺序, 以免在注册后立即到来信号丢失事件)
  21.     if (signal(SIGINT, sig_int) == SIG_ERR)
  22.                 err_sys("signal(SIGINT) error");

  23.         pr_mask("in critical region: \n");

  24.     //3, 这里用错了, 用oldmask释放掉SIGINT,SIGUSR1的阻塞
  25.     //给你看看真正的安全信号编程是怎么回事
  26.     while (!n) { //此处已被锁保护, 检查变量
  27.         sigsuspend(&oldmask); //条件不满足, 原子释放锁+挂起
  28.     }

  29.     //条件满足, 安全打印n
  30.         pr_mask("after return from sigsuspend: %d\n", n);

  31.     //4, 释放掉信号锁
  32.     sigprocmask(SIG_SETMASK, &oldmask, NULL);

  33.     //5, 此后操作n是不安全的.
  34.         pr_mask("program exit: \n");

  35.         exit(0);
  36. }

  37. static void sig_int(int signo)
  38. {
  39.     n = 1;
  40.         pr_mask("\nin sig_int: \n");
  41. }
复制代码
楼主好好吸收一下吧, 对你掌握后面的条件变量也有好处.

论坛徽章:
0
5 [报告]
发表于 2012-11-16 11:55 |只看该作者
你注释后,主进程在你还没有键入信号的时候,就已经退出了。你应该用pause,等待输入信号。回复 3# 你还未够水准呢


   

论坛徽章:
0
6 [报告]
发表于 2012-11-16 12:03 |只看该作者
你这个就有些像互斥锁、条件变量的,安全机制是高了好多的啊。回复 4# linux_c_py_php


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP