sigsuspend 函数疑问

pp25210 2015-01-06 10:04:53

// 这个程序是 apue10.16 节图10_22中的代码.

#include "apue.h"

static void sig_int(int);
void pr_mask(const char*);

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

pr_mask("program start: ");

if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGUSR1);
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: ");

/*
* Pause, allowing all signals except SIGUSR1.
*/
if (sigsuspend(&waitmask) != -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 ...
*/
pr_mask("program exit: ");

exit(0);
}

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

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_ret("sigprocmask error");
} else {
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; /* restore errno */
}


执行
 if (sigsuspend(&waitmask) != -1) 
语句之后进程会被挂起并且会屏蔽除 SIGUSR1 之外的所有信号,.
1. 此时为什么 按 Ctrl+C 键入中断字符之后进程会被唤醒, 而通过 kill -USR1 PID 发送的SIGUSR1并不会使进程唤醒?
2. 将
 if (sigsuspend(&waitmask) != -1) 
改为
 if (sigsuspend(&newmask) != -1) 
之后, 进程应该会被挂起并且屏蔽除 SIGINT 之外的所有信号, 此时按Ctrl+C 键入中断字符为什么进程没有被唤醒?
...全文
168 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Cody2k3 2015-01-06
  • 打赏
  • 举报
回复
引用 楼主 qq252101792 的回复:

// 这个程序是 apue10.16 节图10_22中的代码.

#include "apue.h"

static void	sig_int(int);
void pr_mask(const char*);

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

	pr_mask("program start: ");

	if (signal(SIGINT, sig_int) == SIG_ERR)
		err_sys("signal(SIGINT) error");
	sigemptyset(&waitmask);
	sigaddset(&waitmask, SIGUSR1);
	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: ");

	/*
	 * Pause, allowing all signals except SIGUSR1.
	 */
	if (sigsuspend(&waitmask) != -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 ...
	 */
	pr_mask("program exit: ");

	exit(0);
}

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

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_ret("sigprocmask error");
	} else {
		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;		/* restore errno */
}
执行
 if (sigsuspend(&waitmask) != -1) 
语句之后进程会被挂起并且会屏蔽除 SIGUSR1 之外的所有信号,. 1. 此时为什么 按 Ctrl+C 键入中断字符之后进程会被唤醒, 而通过 kill -USR1 PID 发送的SIGUSR1并不会使进程唤醒? 2. 将
 if (sigsuspend(&waitmask) != -1) 
改为
 if (sigsuspend(&newmask) != -1) 
之后, 进程应该会被挂起并且屏蔽除 SIGINT 之外的所有信号, 此时按Ctrl+C 键入中断字符为什么进程没有被唤醒?
楼主刚好理解反了哈,注释明明是 “allowing all signals except SIGUSR1”, 意即仅block SIGUSR1
zuxi 2015-01-06
  • 打赏
  • 举报
回复
1、如一楼所说,屏蔽USR1信号,接受USR1之外的其他信号; 2、屏蔽SIGINT信号,而Ctrl+C就是发送SIGINT信号,所以进程没有被唤醒。

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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