2011-03-04 39 views
3

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

我打电话选择这样

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

但每当一个信号到达时,它会返回(我用的信号纳米第二定时器)

任何人都知道这是为什么?

回答

5

尝试是这样的:

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

的“剩余时间”指针nanosleep将让你重新启动与睡眠,如果它被中断剩余时间的必要量的照顾。

+0

我会在星期一给我试一试,当我拿回电脑充电器时,但这应该可以工作。谢谢! – 2011-03-06 00:01:22

+0

是的,它在gprof的重度SIGPROF或SIGALRM下工作。 – osgx 2011-05-12 15:27:57

4

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系统而异 - tems;下面是Linux的细节。

如果下列接口中的一个封端的调用由信号处理器中断 ,然后 的 呼叫将被自动如果 回报被 使用SA_RESTART标志信号处理程序后重新开始;否则该呼叫将失败,并出现错误EINTR

通常,检查返回值是否为-1并且errno == EINTR,然后重新调用该函数是纠正此问题的正确方法。

+1

这个答案不完整,不是OP的问题。 Linux对信号(可重新启动的系统调用)具有理想的BSD行为,但是当信号中断时,即使信号处理程序安装了SA_RESTART,它也会作为*特性*被选择* *总是*返回。这个想法是,程序可能(可能确实)想要接收一个信号,就像它会对IO准备好的文件描述符一样。 – 2011-03-04 21:10:37

+1

我认为这是对第二个答案的解释。我正在做的是使用一个信号跟踪时间,试图模仿微处理器的时钟中断接口。所以信号实际上每纳秒调用一次,递增一个时间计数器。这是做这件事的坏方法吗?使用完全相同的信号可能会有100多个进程在同一时间运行。 我正在使用timer_create和CLOCK_PROCESS_CPUTIME_ID为clockid_t创建一个计时器 – 2011-03-06 00:10:43