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;
struct sigaction 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;
struct sigaction 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 SIGALRM signal
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信号被成功屏蔽