pthread_cond_timedwait()如何工作?

问题描述 投票:1回答:1

因此,我试图了解pthread_cond_timedwait()的工作方式,因为在项目同步方面遇到一些问题。这是我想出的代码,但是没有按我认为的那样工作。我的目标是打印时间,等待2秒钟,然后再次打印时间以查看时间的流逝。

//gcc -Wall -pthread timedwait.c -o  exe


#define _OPEN_THREADS                                                           
#include <pthread.h>                                                            
#include <stdio.h>                                                              
#include <time.h>                                                               
#include <errno.h>
#include <stdlib.h>




int main() {                                                                        
  pthread_cond_t cond;                                                          
  pthread_mutex_t mutex;                                                        
  time_t T;                                                                     
  struct timespec t;                                                            

  if (pthread_cond_init(&cond, NULL) != 0) {                                    
    perror("pthread_cond_init() error");                                        
    exit(2);                                                                    
  }                                                                             


  time(&T);                                                                     
  t.tv_sec = T + 2;                                                             
  printf("starting timedwait at %s", ctime(&T));                                
  pthread_cond_timedwait(&cond, &mutex, &t);                                                                                               
  time(&T);                                                                     
  printf("timedwait over at %s", ctime(&T));                                  
}
c multithreading pthreads mutex thread-synchronization
1个回答
0
投票

如果您看到的是等待或多或少立即完成,而不是按照请求等待2秒钟,那么几乎可以肯定是因为timespec对象包含垃圾。

tv_sec当然包含秒数,但是tv_nsec包含纳秒,可能很容易通过说:我不关心它是大于还是小于2秒几纳秒来消除这一点。

但是那不是它的工作方式。如果堆栈上的垃圾恰巧超出范围,它将失败。让我们看看如何故意用垃圾(负数)填充tv_nsec

// gcc -Wall -pthread timedwait.c -o exe        <-- thank you for this

#define _OPEN_THREADS
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

int main() {
  pthread_cond_t cond;
  pthread_mutex_t mutex;
  time_t T;
  struct timespec t;

  if (pthread_cond_init(&cond, NULL) != 0) {
    perror("pthread_cond_init() error");
    exit(2);
  }

  time(&T);
  t.tv_sec = T + 5;
  t.tv_nsec = -1;  // INTENTIONAL JUNK

  printf("starting timedwait at %s", ctime(&T));
  int err = pthread_cond_timedwait(&cond, &mutex, &t);
  if (err != 0)
  {
    printf("pthread_cond_timeout failed: %s\n", strerror(err));
    exit(EXIT_FAILURE);
  }
  time(&T);
  printf("timedwait over at %s", ctime(&T));

  return 0;
}

[当我运行此命令时-用T + 5可以确保确实可以看到等待-它立即失败:

$ ./exe
starting timedwait at Fri Nov 29 19:50:52 2019
pthread_cond_timedwait failed: Invalid argument

但是更改为t.tv_nsec = 0会使它等待您期望的时间。

EDITpthread_cond_timeout添加了特定的错误检查(对@JohnBollinger带有h / t)

© www.soinside.com 2019 - 2024. All rights reserved.