pselect()

来源:互联网 发布:win7网络共享设置软件 编辑:程序博客网 时间:2024/05/22 15:17

很久以来,同事写的一个模块,与串口收发数据的时候,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;
   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信号被成功屏蔽

原创粉丝点击