0
点赞
收藏
分享

微信扫一扫

alarm中断慢系统调用

双井暮色 2022-02-26 阅读 53
c++gnulinux

1. 背景

在阻塞系统调用中,我们经常会遇到一种系统调用返回过慢或永远阻塞的情况。此时我们需要让系统调用能够快速返回,提高系统整体性能。我们可以利用中断机制,使得系统调用被中断而成功返回。

2. 原理

  • 利用alarm函数为进程注册一个闹钟,当闹钟被系统唤醒时将,系统会将SIGALRM信号回馈给进程。
  • SIGALRM信号的默认操作是终止进程。为了让进程不终止,需要利用sigaction函数向系统注册信号处理函数(此处为啥不用signal注册信号处理函数)。

3. sigaction & signal异同点

  • 相同点
    • 均能向系统注册信号处理函数
  • 异同点
    • signal注册信号处理函数,系统调用会自动重启而不会返回
    • sigaction
      • 默认情况下系统调用不会自动重启,函数将返回错误码并值errno为EINTR
      • 只有中断信号的SA_RESTART标志有效时,系统调用才会自动重启

4. 实例

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

static void null_sig_handler(int sig)
{
}

#if 1
static struct sigaction sig_handler = {
    .sa_handler = null_sig_handler,
};
#endif

int main(int argc, const char *argv[])
{
    char buffer[128] = {0};

#if 1
    sigaction(SIGALRM, &sig_handler, NULL);
#else
    signal(SIGALRM, null_sig_handler);
#endif

    for (; ; ) {
        alarm(2);

        int len = read(STDIN_FILENO, buffer, sizeof(buffer));
        printf("len[%d], %s\n", len, strerror(errno));
    }

    return 0;
}

5. 输出结果

len[-1], Interrupted system call
len[-1], Interrupted system call
len[-1], Interrupted system call
len[-1], Interrupted system call
len[-1], Interrupted system call
len[-1], Interrupted system call
len[-1], Interrupted system call
举报

相关推荐

0 条评论