sigsuspend()函数

  在学习sigsuspend()函数时存在一些迷惑,并不太理解书上所叙述的内容。最终,结合网上资源对该函数慢慢有了一点理解,记录下来,以备以后补充。

  在《UNIX环境高级编程》中该函数的提出是在解除信号屏蔽(这里以SIGINT为例)时,信号立即发生,没有等待到pause函数执行的情况下。

sigset_t newmask,oldmask;
sigemptyset(&newmask);
sigaddset(&newmask,SIGINT);

if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0){
err_sys("SIG_BLOCK error");
}
...
if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0){
err_sys("SIG_SETMASK error");
}
//------------>此处正好接受并处理SIGINT信号(与内核如何实现信号有关)
pause();

这样如果后面不再收到信号,那么pause函数就一直挂起。

  

#include <signal.h>
int sigsuspend(const sigset_t *sigmask);

        返回值:-1,并将error设置为EINTR(与pause函数返回值相同)

  进程的信号屏蔽字设置为sigmask指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号前,该进程被挂起(像pause函数一样)。

  等到捕捉到信号,并从该信号的处理函数返回,sigsuspend函数才返回,并将该进程的信号屏蔽字设置为调用sigsuspend前。

  sigsuspend()函数相当于将信号的产生与pause函数同时进行,接收到信号后会停止挂起。(不再会出现先产生信号后再调用pause的情况)

  以下是在实现sleep函数中的应用:

  

//没有使用sigsuspend()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void del_func()
{
}

unsigned int mySleep(unsigned int seconds){
int ret;
struct sigaction act,oldact;

act.sa_handler = del_func;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);

ret = sigaction(SIGALRM,&act,&oldact);
if(ret == -1){
perror("sigaction error");
exit(-1);
}

alarm(seconds);
//----------------------------------->如果此处该进程被cpu挂起,当定时结束发送SIGALRM信号,后面的pause不能接收到(概率极小,但是不可以不考虑)
ret = pause();
if(ret==-1&&errno == EINTR){
printf("pause success\n");
}

ret = alarm(0);
sigaction(SIGALRM,&oldact,NULL);

return ret;
}

int main()
{

while(1){
printf("======\n");
mySleep(3);
}
return 0;
}

=========================================================

//使用sigsuspend()函数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void del_func()
{
}

unsigned int mySleep(unsigned int seconds){
int ret;
struct sigaction act,oldact;
sigset_t newmask,oldmask,waitmask;
unsigned int unslept;

act.sa_handler = del_func;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);

ret = sigaction(SIGALRM,&act,&oldact);
if(ret == -1){
perror("sigaction error");
exit(-1);
}

sigemptyset(&newmask);
sigaddset(&newmask,SIGINT);
sigprocmask(SIG_BLOCK,&newmask,&oldmask);

alarm(seconds);

waitmask = oldmask;

sigsuspend(&waitmask);

unslept = alarm(0);
sigaction(SIGALRM,&oldact,NULL);

sigprocmask(SIG_SETMASK,&oldmask,NULL);

return unslept;
}
int main()
{

while(1){
printf("======\n");
mySleep(3);
}

return 0;
}

原文地址:https://www.cnblogs.com/dog-pi/p/10104297.html

时间: 2024-10-15 18:53:50

sigsuspend()函数的相关文章

sigprocmask , sigpending 和 sigsuspend函数

转自 http://blog.csdn.net/elbort/article/details/7594772 sigprocmask函数: 功能描述:设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞). 用法:#include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); NOTE: If oldset is non-null, the previous value of the sign

sigsuspend函数

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <signal.h> 5 #include <unistd.h> 6 void sigfunc(int signum); 7 int main() 8 { 9 int i; 10 sigset_t newsigset, oldsigset, pendsigset; 11 //1-设置捕获信号 12

sigsuspend sigprocmask函数的用法

一个进程的信号屏蔽字规定了当前堵塞而不能递送给该进程的信号集.调用函数sigprocmask能够检測或更改其信号屏蔽字,或者在一个步骤中同一时候运行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是

sigsuspend sigprocmask函数的使用方法

一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集.调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是一个

Linux C 信号 pause、sigsuspend 的相同与区别

pause函数:       功能:让进程暂停直到信号出现   #include<unistd.h>      intpause();    函数说明:pause()会令目前的进程暂停(进入睡眠状态),直至信号(signal)所中断. 返回值:只返回-1. #include<stdio.h> #include<unistd.h> void deal() { printf(“信号干扰!\n”); } void main() { printf(“进程执行!\n”); sig

APUE读书笔记:关于sigsuspend

sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生.这样来看与另一个函数的作用相同.pause() 加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进

linux c编程:信号(五) sigsuspend

更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信号时SIGINT,实现这一点的一种不正确的方法是: sigset_t    newmask, oldmask; sigemptyset(&newmask); sigaddset(&newmask, SIGINT); /* block SIGINT and save current signal

信号的屏蔽,信号集

1.信号集 POSIX标准定义了数据类型sigset_t #include <signal.h> int sigemptyset(sigset_t *set); 初始化一个信号集,使其不包括任何信号 int sigfillset(sigset_t *set); 用来初始化一个信号集,使其包括所有信号 int sigaddset(sigset_t *set, int signum); 用来向set指定的信号集中添加由signum指定的信号 int sigdelset(sigset_t *set,

POSIX API

POSIX标准总体分析 POSIX,全称为可移植性操作系统接口,是一种关于信息技术的IEEE标准.它包括了系统应用程序接口(API),以及实时扩展(C语言). 该标准的目的是定义了标准的基于UNIX操作系统的系统接口和环境来支持源代码级的可移植性.现在,标准主要提供了依赖C语言的一系列标准服务,再将来的版本中,标准将致力于提供基于不同语言的规范. 该标准对核心需求部分定义了一系列任何编程语言都通用的服务,这一部分服务主要从其功能需求方面阐述,而非定义依赖于编程语言的接口.语言规范主要有两部分组成