select与pselect的信号屏蔽
pselect()?函數的原型是:int?pselect(int?nfds,?fd_set?*readfds,?fd_set?*writefds,
???????????????????fd_set?*exceptfds,?const?struct?timespec?*timeout,?const?sigset_t?*sigmask);
它和?select()?函數基本相同,區別在于兩個不同的參數,一個是?struct?timespec?*timeout,另一個是?sigset_t?*sigmask?。
struct?timespec?結構定義為:
??struct?timespec?{
???????????????long????tv_sec;?????????
???????????????long????tv_nsec;????????
???????????};
其中的時間表示秒和納秒。和?select()?不同,每次超時后,pselect()?并不會去修改這個時間參數,也就是說,沒有必要再次對這個時間參數進行初始化。
對于最后一個參數?sigmask?表示信號屏蔽掩碼,設置掩碼可以對相應的信號進行屏蔽,這樣pselect就一直不會被屏蔽的信號所中斷。
select等待期間不想被中斷的方法有兩個:
其一:pselect?代替select
#include?"unp.h"
void
sig_alarm(int?signo)
{
????????printf("%d\n",signo);
????????if(signo?==?SIGALRM)
????????{
????????????????printf("SIGALRM\n");
????????}
????????else?if(signo?==?SIGVTALRM)
????????{
????????????????printf("SIGVTALRM\n");
????????}
}
int
main()
{
????????sigset_t?sigmask;
????????fd_set?rset;
????????ssize_t?nread;
????????char?buf[MAXLINE];
????????int?maxfd;
????????struct?itimerval?value;
????????signal1(SIGALRM,sig_alarm);
????????value.it_interval.tv_sec?=?3;
????????value.it_interval.tv_usec?=?0;
????????value.it_value.tv_sec?=?1;
????????value.it_value.tv_usec?=?0;
????????if(setitimer(ITIMER_REAL,&value,NULL)?==?-1)
????????{
????????????????printf("setitimer?error.\n");
????????????????return?0;
????????}
????????if(sigemptyset(&sigmask)?==??-1)
????????{
????????????????printf("sigemptyset?error.\n");
????????????????return?0;
????????}
????????if(sigaddset(&sigmask,SIGALRM)?==?-1)
????????{
????????????????printf("sigaddset?error.\n");
????????????????return?0;
????????}
????????while(1)
????????{
????????????????FD_ZERO(&rset);
????????????????FD_SET(fileno(stdin),&rset);
????????????????maxfd?=?fileno(stdin)?+?1;
????????????????int?nready?=?pselect(maxfd,&rset,NULL,NULL,NULL,&sigmask);
????????????????//printf("select?called.%d\n",nready);
????????????????if(nready?<?0)
????????????????{
????????????????????????if(errno?==?EINTR)
????????????????????????{
????????????????????????????????printf("interruped.\n");
????????????????????????}
????????????????}
????????????????else
????????????????{
????????????????????????int?nread?=?ReadLine(fileno(stdin),buf,MAXLINE);
????????????????????????if(nread?<?0)
????????????????????????{
????????????????????????????????printf("讀取失敗!\n");
????????????????????????????????continue;
????????????????????????}
????????????????//??????printf("nread:?%d\n",nread);
????????????????????????//Write(stdin,buf,nread);
????????????????????????printf("%s",buf);
????????????????}
????????}
}
其二:運用sigprocmask函數
#include?"unp.h"
void
sig_alarm(int?signo)
{
????????printf("%d\n",signo);
????????if(signo?==?SIGALRM)
????????{
????????????????printf("SIGALRM\n");
????????}
????????else?if(signo?==?SIGVTALRM)
????????{
????????????????printf("SIGVTALRM\n");
????????}
}
int
main()
{
????????sigset_t?sigmask;
????????fd_set?rset;
????????ssize_t?nread;
????????char?buf[MAXLINE];
????????int?maxfd;
????????struct?itimerval?value;
????????signal1(SIGALRM,sig_alarm);
????????value.it_interval.tv_sec?=?3;
????????value.it_interval.tv_usec?=?0;
????????value.it_value.tv_sec?=?1;
????????value.it_value.tv_usec?=?0;
????????if(setitimer(ITIMER_REAL,&value,NULL)?==?-1)
????????{
????????????????printf("setitimer?error.\n");
????????????????return?0;
????????}
????????if(sigemptyset(&sigmask)?==??-1)
????????{
????????????????printf("sigemptyset?error.\n");
????????????????return?0;
????????}
????????if(sigaddset(&sigmask,SIGALRM)?==?-1)
????????{
????????????????printf("sigaddset?error.\n");
????????????????return?0;
????????}
????????sigprocmask(SIG_BLOCK,&sigmask,NULL);
????????while(1)
????????{
????????????????FD_ZERO(&rset);
????????????????FD_SET(fileno(stdin),&rset);
????????????????maxfd?=?fileno(stdin)?+?1;
????????????????//int?nready?=?pselect(maxfd,&rset,NULL,NULL,NULL,&sigmask);
????????????????//printf("select?called.%d\n",nready);
???????????????int?nready?=?select(maxfd,&rset,NULL,NULL,NULL);
????????????????if(nready?<?0)
????????????????{
????????????????????????if(errno?==?EINTR)
????????????????????????{
????????????????????????????????printf("interruped.\n");
????????????????????????}
????????????????}
????????????????else
????????????????{
????????????????????????int?nread?=?ReadLine(fileno(stdin),buf,MAXLINE);
????????????????????????if(nread?<?0)
????????????????????????{
????????????????????????????????printf("讀取失敗!\n");
????????????????????????????????continue;
????????????????????????}
????????????????//??????printf("nread:?%d\n",nread);
????????????????????????//Write(stdin,buf,nread);
????????????????????????printf("%s",buf);
????????????????}
????????}
}
比較兩種方法,都可以有效防止select被信號中斷,經我測試,兩者還是有區別的,第一種當你在終端輸入數據時,時鐘信號處理函數是會被執行的,而第二種則徹底屏蔽了時鐘信號。
總結
以上是生活随笔為你收集整理的select与pselect的信号屏蔽的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浙商银行战旗卡取现手续费及利息怎么算
- 下一篇: 做个核酸 假牙都掉了出来:不只一个大白被