int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask);
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
sigset_t origmask;
sigprocmask(SIG_SETMASK, &sigmask, &origmask);
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL);
很久以来,同事写的一个模块,与串口收发数据的时候,SELECT()函数等待的时间长点,就会被模块里设置的时钟信号打断,最近看到了一个新的函数pselect(),研究了一把,收获不小!!
现在发现,SELECT()函数等待的这段时间内不想被别的信号打断的方法有两
其一:
用pselect()函数
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/select.h>
#define BUFFSIZE 80
void sig_int(int signo);
void err_sys(const char *p_error);
void sig_alrm(int signo)
{
char s[] ="receive";
psignal(signo, s);
return;
}
int
main(int argc, char **argv)
{
int maxfdp1;
fd_set rset;
sigset_t sigmask;
ssize_t nread;
char buf[BUFFSIZE];
sigset_t sigset;
structsigaction act;
//set SIGALRM signal handler
act.sa_handler= sig_alrm;
if(sigemptyset(&act.sa_mask) ==-1)
err_sys("sigemptyset");
act.sa_flags= 0;
if(sigaction(SIGALRM, &act, NULL) == -1)
err_sys("sigaction");
//initialize signal set and addition SIGALRM into sigset
if(sigemptyset(&sigset) == -1)
err_sys("sigemptyet");
if(sigaddset(&sigset, SIGALRM) == -1)
err_sys("sigaddset");
alarm(1);
FD_ZERO(&rset);
FD_SET(STDIN_FILENO, &rset);
maxfdp1 = STDIN_FILENO + 1;
if (pselect(maxfdp1, &rset, NULL, NULL, NULL,&sigset) <= 0)
err_sys("pselect error");
if (FD_ISSET(STDIN_FILENO, &rset))
{
if ((nread = read(STDIN_FILENO, buf, BUFFSIZE)) == -1)
err_sys("read error");
if (write(STDOUT_FILENO, buf, nread) != nread)
err_sys("write error");
}
exit(0);
}
void
sig_int(int signo)
{
char s[] ="received";
psignal(signo, s);
return;
}
void
err_sys(const char *p_error)
{
perror(p_error);
exit(1);
}
上段代码如果没有CTRL+C送上一个SIGINT信号,将永远阻塞在与用户的交互上,ALARM产生的SIGALRM信号永远打断不了PSELECT,ALARM信号被成功屏蔽
方法2:sigprocmask()
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/select.h>
#define BUFFSIZE 80
void sig_int(int signo);
void err_sys(const char *p_error);
void sig_alrm(int signo)
{
char s[] ="receive";
psignal(signo, s);
return;
}
int
main(int argc, char **argv)
{
int maxfdp1;
fd_set rset;
sigset_t sigmask;
ssize_t nread;
char buf[BUFFSIZE];
sigset_t sigset;
structsigaction act;
//set SIGALRM signal handler
act.sa_handler= sig_alrm;
if(sigemptyset(&act.sa_mask) ==-1)
err_sys("sigemptyset");
act.sa_flags= 0;
if(sigaction(SIGALRM, &act, NULL) == -1)
err_sys("sigaction");
//initialize signal set and addition SIGALRM into sigset
if(sigemptyset(&sigset) == -1)
err_sys("sigemptyet");
if(sigaddset(&sigset, SIGALRM) == -1)
err_sys("sigaddset");
//block SIGALRMsignal
if(sigprocmask(SIG_BLOCK, &sigset, NULL) == -1)
err_sys("sigprocmask");
//generate SIGALRM signal
alarm(1);
FD_ZERO(&rset);
FD_SET(STDIN_FILENO, &rset);
maxfdp1 = STDIN_FILENO + 1;
if (select(maxfdp1, &rset, NULL, NULL, NULL)<= 0)
err_sys("pselect error");
if (FD_ISSET(STDIN_FILENO, &rset))
{
if ((nread = read(STDIN_FILENO, buf, BUFFSIZE)) == -1)
err_sys("read error");
if (write(STDOUT_FILENO, buf, nread) != nread)
err_sys("write error");
}
exit(0);
}
void
sig_int(int signo)
{
char s[] ="received";
psignal(signo, s);
return;
}
void
err_sys(const char *p_error)
{
perror(p_error);
exit(1);
}
同样,上段代码如果没有CTRL+C送上一个SIGINT信号,将永远阻塞在与用户的交互上,ALARM产生的SIGALRM信号永远打断不了SELECT,ALARM信号被成功屏蔽.
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |