C问题:求教:R.Stevens 中的一个问题(kingofark)

kingofark 2001-10-15 07:54:54
[问题名称]:

Kingofark求教:R.Stevens<UNIX环境高级编程>中的一个问题(kingofark)


[问题的环境]:

我的机子:Red Hat Linux 7.1 (Kernel 2.4.2-2)


[问题的地点]:

机械工业出版社:Richard Stevens《UNIX环境高级编程》第10章 信号

第229页至第230页:程序10-15 保护临界区不被信号中断


[问题的提出]:

书中说到,

“运行程序10-15得到下面的输出:

$ a.out
in critical region: SIGINT
^? 键入自定义的中断字符
in sig_int: SIGINT
after return from sigsuspend: SIGINT”

本程序演示了如何在临界区(即代码中的 critical region 那个位置)屏蔽掉一些中断信号。但是,我阅读到这里的时候,对书中所显示的输出结果很不满意,因为三条输出竟然都是SIGINT。

按照程序的本意,结果中的第一条(即“in critical region:”)的输出应该是和第三条(即“after return from sigsuspend:”)的输出是一样的(这两条显示的都是临界区中被屏蔽的中断信号),而它们并不一定与第二条(即“in sig_int:”)的输出相同。

然而在书中,却恰好是一个三条输出结果都相同的例子。我觉得对于我这样一个初学者来说,即使没有看不懂,至少也是令人觉得很不爽——这样的输出结果,非要让人来一个完全不必要的阿Q式“凡事须得研究才能明白”的研究才能消除对其的迷惑。

于是,我对程序10-15作了一点小的修改。只要让临界区多屏蔽一个中断信号,那么第一、三条的输出结果就会与第二条的输出结果不同,从而使得整个程序示例的输出结果清晰明了,明白无误。具体改动:只要在一开始设置newmask信号集的地方(即代码中sigaddset(&newmask,SIGINT);这一句的地方,)再加上一句sigaddset(&newmask,其它中断信号);就可以了。我加上了一句sigaddset(&newmask,SIGUSR1);,得到如下的输出结果:

$ a.out
in critical region: SIGINT SIGUSR1
^? 键入自定义的中断字符
in sig_int: SIGINT
after return from sigsuspend: SIGINT SIGUSR1

这样多好!


[问题的解答]:

毕竟上面的讨论问题是我自己琢磨的,所以也不敢保证是对的,特此希望各位有兴趣的同胞也看看,有什么问题和想法或者异议,跟我说说,也好让我学习学习。


谢谢!


附:书中的程序10-15代码及相关的代码程序10-10


// -- 程序10-15 ----------------------------------

#include <signal.h>
#include "ourhdr.h"

static void sig_int(int);

int
main(void)
{
sigset_t newmask, oldmask, zeromask;

if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");

sigemptyset(&zeromask);

sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
/* block SIGINT and save current signal mask */
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");

/* critical region of code */
pr_mask("in critical region: ");

/* allow all signals and pause */
if (sigsuspend(&zeromask) != -1)
err_sys("sigsuspend error");
pr_mask("after return from sigsuspend: ");

/* reset signal mask which unblocks SIGINT */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");

/* and continue processing ... */
exit(0);
}

static void
sig_int(int signo)
{
pr_mask("\nin sig_int: ");
return;
}


//-- 程序10-10 ---------------------------------------

#include <errno.h>
#include <signal.h>
#include "ourhdr.h"

void
pr_mask(const char *str)
{
sigset_t sigset;
int errno_save;

errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0)
err_sys("sigprocmask error");

printf("%s", str);
if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
/* remaining signals can go here */
printf("\n");
errno = errno_save;
}
...全文
167 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
kingofark 2001-10-25
  • 打赏
  • 举报
回复
通过这个回复,让贴子上升给大家看看。应该不会只有我一个人看这本书吧!?
kingofark 2001-10-18
  • 打赏
  • 举报
回复
呵呵,没人理我,呵呵。
eternalee 2001-10-15
  • 打赏
  • 举报
回复
看看

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧