Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10115
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-10 18:46
文章分类
文章存档

2013年(6)

我的朋友

分类: C/C++

2013-09-29 16:17:35

很久以来,同事写的一个模块,与串口收发数据的时候,SELECT()函数等待的时间长点,就会被模块里设置的时钟信号打断,最近看到了一个新的函数pselect(),研究了一把,收获不小!!
现在发现,SELECT()函数等待的这段时间内不想被别的信号打断的方法有两
其一:
用pselect()函数
#include        
#include        
#include        
#include        
#include        
#include        
#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        
#include        
#include        
#include        
#include        
#include        
#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信号被成功屏蔽
阅读(332) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~