【问题标题】:Using sleep and select with signals使用 sleep 和 select 信号
【发布时间】:2011-03-04 19:53:25
【问题描述】:

我想使用select() 函数等待1 秒,因为我的程序使用信号来控制东西,所以sleep() 会过早返回。奇怪的是,当使用select() 时,它也会过早返回。

我这样调用 select

struct timeval timeout;    
timeout.tv_sec = 10;  
timeout.tv_usec = 1000000; 
select (0 ,NULL, NULL, NULL, &timeout);

但是每当信号到达时,它就会返回(我使用的是纳秒计时器)

有人知道为什么吗?

【问题讨论】:

    标签: c signals sleep select-function


    【解决方案1】:

    试试这样的:

    struct timespec timeout;
    timeout.tv_sec = 10;
    timeout.tv_nsec = 0;
    while (nanosleep(&timeout, &timeout) && errno == EINTR);
    

    指向nanosleep 的“剩余时间”指针将负责让您在睡眠中断时以必要的剩余时间重新启动睡眠。

    【讨论】:

    • 我会在星期一拿回电脑充电器时试一试,但这应该可以。谢谢!
    【解决方案2】:

    man 7 signal 说:

    信号处理程序中断系统调用和库函数

    如果在系统调用或库时调用信号处理程序 函数调用被阻塞,然后 要么:

       * the call is automatically restarted after the signal handler
         returns; or
    
       * the call fails with the error EINTR.
    

    这两种行为中的哪一种取决于接口和 信号处理程序是否 是使用 SA_RESTART 标志建立的(参见 sigaction(2))。 细节因 UNIX 系统而异 条款;下面是 Linux 的详细信息。

    如果对以下接口之一的阻塞调用是 被信号处理程序中断,然后 这 call 将在信号处理程序后自动重新启动 如果 SA_RESTART 标志为 用过的;否则调用将失败并返回错误 EINTR

    一般来说,检查返回值是否为 -1 和 errno == EINTR 然后重新调用函数是纠正此问题的正确方法。

    【讨论】:

    • 这个答案不完整,不是 OP 的问题。 Linux 对信号(可重新启动的系统调用)具有健全的 BSD 行为,但 select always 在被信号中断时返回,即使信号处理程序与 SA_RESTART 一起安装,作为 功能。这个想法是程序可能(可能确实)想要对接收到的信号采取行动,就像它对准备好 IO 的文件描述符采取行动一样。
    • 我认为这是对第二个答案实施的解释。我正在做的是使用信号来跟踪时间,试图模仿微处理器的时钟中断接口。所以信号实际上每纳秒被调用一次,增加一个时间计数器。这是一种不好的做法吗?可能有 100 个进程使用完全相同的信号同时运行。我正在使用使用 timer_create 和 CLOCK_PROCESS_CPUTIME_ID 创建的计时器作为clockid_t
    猜你喜欢
    • 1970-01-01
    • 2020-02-22
    • 2020-09-02
    • 1970-01-01
    • 2017-01-13
    • 2015-01-20
    • 1970-01-01
    • 2020-03-25
    • 2015-01-28
    相关资源
    最近更新 更多