Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1612839
  • 博文数量: 695
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4027
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-20 21:22
文章分类

全部博文(695)

文章存档

2018年(18)

2017年(74)

2016年(170)

2015年(102)

2014年(276)

2013年(55)

分类: LINUX

2013-12-23 14:19:09

系统调用被信号中断和自动重启动


    当进程正在执行一个系统调用时,如果被信号中断,这时会发生什么呢?

     当一个低速调用阻塞期间捕捉到一个信号, 则该系统调用就被中断不再继续执行。 该系统调用返回出错,起errono设置为EINTR。 因为发生信号, 进程捕捉到它, 这将是一个很好的机会来唤醒阻塞的系统调用。

     但有一个问题就是如果该系统调为read(), 正在等待终端输入, 如果被信号中断的话, 难免会影响整个程序的正确性, 所以有些系统使这类系统调用自动重启动。就是一旦被某信号中断, 立即再启动。

如下面的signal1函数实现:

#include
#include "ourhdr.h"

typedef void Sigfunc(int);

Sigfunc *
signal1(int signo, Sigfunc *func)
{
        struct sigaction        act, oact;

        act.sa_handler = func;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;

        if (signo ==SIGALRM)
        {
#ifdef SA_INTERRUPT
                act.sa_flags |= SA_INTERRUPT;
#endif
        }
        else
        {
#ifdef SA_RESTART
                act.sa_flags |= SA_RESTART;   /*这里对所有的信号都设置了自动再启动,唯独没有SIGALRM*/
#endif
        }

        if (sigaction(signo, &act, &oact)<0)
                return(SIG_ERR);
        return (oact.sa_handler);
}

    为什么偏偏面对SIGALRM信号, 系统调用不设置自动重启动呢? 这时为了我们方便给read等低速系统调用定时。 我们不希望它一遇到某个信号变自动重启动,也不希望它无限制的阻塞下去。 于是用alarm()进行定时, 一旦超出某个时间, 便被ALRM信号中断唤醒,且不再重启动。


    下面这段程序用来测试上面的signal1函数, 对一个read系统调用, 如何给它定时的:

#include
#include "ourhdr.h"
#include "10-12.c"

#define MAXLINE 1024

static void sig_alrm(int);

int
main(void)
{
        int     n;
        char line[MAXLINE];

        if (signal1(SIGALRM, sig_alrm) == SIG_ERR)
                perror("signal");

        alarm(10);
        if ( (n = read(STDIN_FILENO, line, MAXLINE)) < 0)
                perror("read");
        alarm(0);
        write(STDOUT_FILENO, line, n);
        write(STDOUT_FILENO, "exit\n", 5);

        exit(0);
}

static void
sig_alrm(int signo)
{
        write(STDOUT_FILENO, "recieved signal -ALRM\n", 22);
        return;
}

    在我的系统中, 如果调用默认的signal函数, 该read()系统调用将会自动重启动, 所谓的alarm定时也就不起作用了。

阅读(983) | 评论(0) | 转发(0) |
0

上一篇:linux下vi命令大全

下一篇:sigaction函数

给主人留下些什么吧!~~