日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

select与pselect的信号屏蔽

發(fā)布時(shí)間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 select与pselect的信号屏蔽 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

pselect()?函數(shù)的原型是:int?pselect(int?nfds,?fd_set?*readfds,?fd_set?*writefds,
???????????????????fd_set?*exceptfds,?const?struct?timespec?*timeout,?const?sigset_t?*sigmask);
它和?select()?函數(shù)基本相同,區(qū)別在于兩個(gè)不同的參數(shù),一個(gè)是?struct?timespec?*timeout,另一個(gè)是?sigset_t?*sigmask?。


struct?timespec?結(jié)構(gòu)定義為:
??struct?timespec?{
???????????????long????tv_sec;?????????
???????????????long????tv_nsec;????????
???????????};


其中的時(shí)間表示秒和納秒。和?select()?不同,每次超時(shí)后,pselect()?并不會(huì)去修改這個(gè)時(shí)間參數(shù),也就是說,沒有必要再次對(duì)這個(gè)時(shí)間參數(shù)進(jìn)行初始化。
對(duì)于最后一個(gè)參數(shù)?sigmask?表示信號(hào)屏蔽掩碼,設(shè)置掩碼可以對(duì)相應(yīng)的信號(hào)進(jìn)行屏蔽,這樣pselect就一直不會(huì)被屏蔽的信號(hào)所中斷。


select等待期間不想被中斷的方法有兩個(gè):

其一: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);
????????????????}
????????}
}

其二:運(yùn)用sigprocmask函數(shù)


#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被信號(hào)中斷,經(jīng)我測(cè)試,兩者還是有區(qū)別的,第一種當(dāng)你在終端輸入數(shù)據(jù)時(shí),時(shí)鐘信號(hào)處理函數(shù)是會(huì)被執(zhí)行的,而第二種則徹底屏蔽了時(shí)鐘信號(hào)。

總結(jié)

以上是生活随笔為你收集整理的select与pselect的信号屏蔽的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。