首页 文章

如何用适当的信号中断epoll_pwait? [重复]

提问于
浏览
2

可能重复:使用非IO事件中断epoll_wait,无信号

我有一个线程,当前正在使用epoll_wait来标记某些套接字上的数据到达 . timeout参数当前设置为零 .

但是,该线程还执行其他任务 . 我想要做的就是改变它,这样如果没有工作要做,那就让它无限期或长时间用完 . 当没有实际工作时,这将大大减少浪费的CPU周期 .

整个过程主要是由一个消息到达线程安全锁定空闲队列 .

所以,我认为应该发生的是我应该使用epoll_pwait唤醒线程长时间的超时 .

但是,我不确定发送它的信号以及如何完成 . 我不熟悉Linux信号 .

以下与我目前的情况类似 . 显着缩短以显示概念 . 如果您发现了一个错误,请不要指出它,这只是我在这里输入的一个插图,以帮助您理解我想要实现的目标 .

// Called from another thread...
void add_message_to_queue(struct message_t* msg)
{
    add_msg(msg);
    raise( ? );  // wake the state machine?
}


// different thread to the above.
main_thread()
{
    struct message_t msg;
    while (msg = get_message_from_queue())
      process_message(msg);

    timeout = work_available ? 0 : -1;

    nfds = epoll_pwait(epfd, events, MAX_EPOLL_EVENTS, timeout);
    for (i = 0; i < nfds; ++i)
    {
        if ((events[i].events & EPOLLIN) == EPOLLIN)
        {
           /// do stuff
        }
    }

    run_state_machines();
}

所以我想我的问题是,这是正确的方法吗?如果是这样,我发送什么信号,我需要定义信号处理程序,还是我可以使用信号处理“忽略”并仍然被唤醒?

1 回答

  • 2

    而不是信号,考虑使用pipe . 创建管道并将管道读取端的文件描述符添加到epoll . 如果要唤醒epoll_wait调用,只需将1个字符写入管道的写入端 .

    int read_pipe;
    int write_pipe;
    void InitPipe()
    {
        int pipefds[2] = {};
        epoll_event ev = {};
        pipe(pipefds, 0);
        read_pipe = pipefds[0];
        write_pipe = pipefds[1];
    
        // make read-end non-blocking
        int flags = fcntl(read_pipe, F_GETFL, 0);
        fcntl(write_pipe, F_SETFL, flags|O_NONBLOCK);
    
        // add the read end to the epoll
        ev.events = EPOLLIN;
        ev.data.fd = read_pipe;
        epoll_ctl(epfd, EPOLL_CTL_ADD, read_pipe, &ev);
    
    }
    
    void add_message_to_queue(struct message_t* msg)
    {
        char ch = 'x';
        add_msg(msg);
        write(write_pipe, &ch, 1);
    }
    
    main_thread()
    {
        struct message_t msg;
        while (msg = get_message_from_queue())
          process_message(msg);
    
        timeout = work_available ? 0 : -1;
    
        nfds = epoll_wait(epfd, events, MAX_EPOLL_EVENTS, timeout);
    
        for (i = 0; i < nfds; ++i)
        {
            if (events[i].data.fd == read_pipe)
            {
    
                // read all bytes from read end of pipe
                char ch;
                int result = 1;
                while (result > 0)
                {
                    result = read(epoll_read, &ch, 1);
                }
            }
    
            if ((events[i].events & EPOLLIN) == EPOLLIN)
            {
               /// do stuff
            }
        }
    
        run_state_machines();
    }
    

相关问题