pselect()

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值