如何阻止,捕获和处理来自非阻塞CLI的多个信号和击键事件?

时间:2016-07-24 12:14:36

标签: c++ c unix signals

  • 语言:C ++和C
  • 操作系统:类UNIX(POSIX)
  • 上下文:通过简单的非阻塞命令行界面对文件或来自另一个程序的管道进行抽象/可视化抽象数据流的实时过程
  • 说明sig_handler()sig_timed_kbhit()是由用户点击<enter>或^导致轻松调度实时执行终止的函数C,从文件或STDIN重定向/管道处理数据。
  • 参数fdSTDIN_FILENOint在调用函数中返回的open("/dev/tty", O_RDWR)值。 struct timeval tv调用函数传递的超时期限
  • 问题:它还必须阻止,捕获和处理SIGTSTPSIGCONT,也可能SIGQUIT。我还没有看到如何做到这一点的例子。是否需要调用sigfillset(),需要多个(嵌套?)信号处理程序,struct sigaction s,sigset_t s?
  • 到目前为止
  • 研究: 我有一个完全正常工作的解决方案,用于处理<enter>SIGINT

SIGINT的通用信号处理程序:

void sig_handler(int signo)
{
    if (signo == SIGINT){
        std::cout<<"\nreceived SIGINT"<<std::endl;
        //code for handling SIGINT
        ;
}

处理<enter>^C的工作代码:

bool sig_timed_kbhit(int fd, struct timeval tv)
{
    // Installing signal handler for SIGINT
    struct sigaction s;
    s.sa_handler = sig_handler;
    sigemptyset(&s.sa_mask);
    s.sa_flags = 0;
    sigaction(SIGINT, &s, NULL);

    // Blocking SIGINT
    sigset_t sigset, prev_set;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGINT);
    sigprocmask(SIG_BLOCK, &sigset, &prev_set);

    struct timespec ts;
    TIMEVAL_TO_TIMESPEC(&tv, &ts);
    fd_set read_fd;
    FD_ZERO(&read_fd);
    FD_SET(fd, &read_fd);

    if (pselect(fd+1, &read_fd, NULL, NULL, &ts, &prev_set) < 0)
        std::cerr<<"select"<<std::endl;

    bool   b = (FD_ISSET(fd, &read_fd)) ;
    return b;
}

任何有关如何优雅地解决此类任务的建议都将受到赞赏。提前谢谢。

0 个答案:

没有答案