alarm中断慢系统调用

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值