clock_nanosleep不返回-1 /设置errno EINTR – LINUX

我是一个Linux新手。 我正在尝试使用clock_nanosleep来实现一个简单的任务。 问题是,clock_nanosleep在被信号中断之后没有将errno设置到EINTR。 我曾尝试重置SA_RESTART标志。 但是,没有成功。 这是我的代码。 谢谢。

void signalHandler( int signum ) { printf("Interrupt signal received.\n"); } void *periodic_thread (void *param) { struct itimerspec its; struct sigevent sig; struct timespec next, period; sigset_t blocked; siginfo_t si; timer_t mytimer; int i, j; /* create a timer that will be used to periodically send a signal */ sig.sigev_notify = SIGEV_SIGNAL; sig.sigev_signo = SIGUSR1; sig.sigev_value.sival_ptr = &sig; timer_create(CLOCK_REALTIME, &sig, &mytimer); struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &signalHandler; sigaction(SIGUSR1, &sa, NULL); /* set the periodic timer */ its.it_value.tv_sec = 8; its.it_value.tv_nsec = 00000000; its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0; ; period.tv_sec = 5; period.tv_nsec = 00000000; timer_settime(mytimer, 0, &its, NULL); printf("periodic thread started...\n"); j=1; i = clock_gettime(CLOCK_MONOTONIC, &next); while(1) { next.tv_sec = next.tv_sec + period.tv_sec; next.tv_nsec = next.tv_nsec + period.tv_nsec; i = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, 0); printf("I am done \n"); if((i == -1) && (errno == EINTR)) break; } printf("...periodic thread end!\n"); timer_delete(mytimer); return NULL; } int main() { pthread_t mythread; pthread_attr_t myattr; //struct sched_param myparam; void *returnvalue; sigset_t blocked; /* initializes the thread attribute */ pthread_attr_init(&myattr); printf("starting a periodic thread...\n"); pthread_create(&mythread, &myattr, periodic_thread, NULL); pthread_attr_destroy(&myattr); /* wait the end of the thread we just created */ pthread_join(mythread, &returnvalue); printf("ending main...\n"); return 0; } 

输出>>

  starting a periodic thread... periodic thread started... I am done Interrupt signal received. I am done I am done continues.. (Does not break the while(1)) 

我想出了这个问题,

问题:主线程被信号中断,而不是由clock_nanosleep构成的子线程。

解决方案1:使用“pthread_sigmask(SIG_BLOCK,&blocked,NULL)”在主线程中阻塞SIGUSR1

解决方案2:使用“sigev_notify = SIGEV_THREAD_ID”生成线程特定的事件。 (适用于计时器)

谢谢

与大多数传统的系统调用不同, clock_nanosleep在失败时不会返回-1。 根据POSIX规范 :

如果clock_nanosleep()函数由于被信号中断而返回,它将返回相应的错误值。

所以请尝试检查它是否返回EINTR

(更新的POSIX接口倾向于返回错误代码,而不是依赖于errno 。有人的想法是更现代化和线程安全,我猜。最终的结果只是混乱,但IMO)。