clock_nanosleep函数不会返回-1 / 设置errno为EINTR - LINUX

3

我是一个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)) 

1
在线程读取属性之前摧毁它可能不是一个好主意。交换销毁和连接操作的顺序。或者使用默认属性(向pthread_create()传递空指针),因为您未设置任何非默认属性。 - Jonathan Leffler
2个回答

1
我找到了问题,
问题:主线程被信号打断,而不是子线程使用clock_nanosleep。
解决方案1:在主线程中使用“pthread_sigmask(SIG_BLOCK, &blocked, NULL)”阻止SIGUSR1。
解决方案2:使用“sigev_notify = SIGEV_THREAD_ID”生成特定于线程的事件。(适用于计时器)
谢谢

0

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

如果clock_nanosleep()函数因被信号中断而返回,则应返回相应的错误值。

因此,请尝试检查它是否返回EINTR

(较新的POSIX接口倾向于返回错误代码,而不是依赖于errno。我猜这是某人更现代和线程安全的想法。但是,最终结果只是一团糟,我个人认为。)


我已经验证过了。这是输出: 开始一个周期性线程... 周期性线程已启动... 我完成了.. 返回值:0 接收到中断信号。 我完成了.. 返回值:0 我完成了.. 返回值:0 我完成了.. 返回值:0 - Starscream09

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接