signal() 和 ualarm() 与 select() 冲突

问题描述 投票:0回答:1

我有一个

select()
每秒更新我的 UI,并处理来自 X11 的用户操作。这是此源代码的片段:

XEvent e;
/* Input file descriptor */
fd_set in_fd;
/* Get the file descriptor of the link with X11 */
int dpy_fd = ConnectionNumber(disp->dpy);

while (!finish) {
  FD_ZERO(&in_fd);
  FD_SET(dpy_fd, &in_fd);

  if (select(dpy_fd+1, &in_fd, 0, 0, &tv)) {
    printf("Event Received!\n");
    XNextEvent(disp->dpy, &e);
    /* do something */
  }
  else {
    printf("Timer Fired!\n");
    /* do something else*/
  }
}

到目前为止,一切都还好。

同时,我需要使用警报每 500 毫秒执行另一件事,所以我实现了这个:

static void timer_handler(int sig)
{
  signal(SIGALRM, SIG_IGN); /* ignore this signal */
  printf("timer_handler\n");
  signal(SIGALRM, timer_handler); /* reinstall the handler */
}

int test_timer()
{
  printf("test_timer\n");

  signal(SIGALRM, timer_handler);
  ualarm(1, 500000); /* every 500 ms */

  return 0;
}

我每 500 毫秒就会在控制台中收到 timer_handler,但这就像它消耗了

select()
中的事件,因为我不再有 Timer Fired!(不再更新 UI)。如果我按下某个键或将鼠标移到 UI 上,我会在控制台中收到Event Received!,并且警报仍在响应。

select()
是否使用了SIGALRM信号?我做错了什么?我只想使用
select()
来处理UI和警报以每500毫秒调用一个方法(此方法复用硬件性能计数器)。

c signals alarm posix-select
1个回答
2
投票

SIGALRM
EINTR
调用中触发
select(2)
错误。您必须检查系统调用是否返回超时、文件描述符事件或错误(以及哪种错误):

while (!finish) {
    int s;

    FD_ZERO(&in_fd);
    FD_SET(dpy_fd, &in_fd);

    s = select(dpy_fd+1, &in_fd, 0, 0, &tv)
    if (s > 0) {
        printf("Event Received!\n");
        XNextEvent(disp->dpy, &e);
        /* do something */
    } else if (s == 0) {
        /* This is probably where we should break the loop or reset the
         * select(2) timeout, so... I chose to break it. If you don't
         * do something about it you're gonna end up in a busy wait. */
        break;
    } else {
        if (errno == EINTR) {
            /* We've been interrupted by another signal, and it might be
             * because of the alarm(3) (using the SIGALRM) or any other
             * signal we have received externally. */
            continue;
        }
        perror("Select failed");
        /* Handle the error properly. */
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.