2009-09-28 71 views
5
void wait(int timeInMs) 
{ 
    struct timespec timeToWait; 
    timeToWait.tv_sec = 5; 
    timeToWait.tv_nsec = timeInMs*1000; 

    int rt; 

    pthread_mutex_lock(&fakeMutex); 
    rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait); 
    pthread_mutex_unlock(&fakeMutex); 
} 

我正在使用此代碼嘗試讓線程等待一段時間,但它根本不起作用。沒有錯誤,它只是不會讓程序執行得更慢。pthread_cond_timedwait()

我在想也許每個線程都需要它自己的條件和互斥量,但這對我來說確實沒有意義。

+1

不要緊,在這個例子中,但納秒= 1,000,000 *毫秒。 – 2009-09-28 13:36:19

回答

2

該代碼沒有睡覺,它檢查一段時間的條件。因爲你不可能設置cond,它只是立即返回。

如果你不願意圍繞信號同步線程,那麼pthread_cond _wait不是你所需要的。檢查here條件變量是如何工作的。

如果你想秒精度睡覺用 sleep

如果你想用微秒精度使用select與timevals睡覺

+0

但睡眠停止整個過程,我需要線程等待。 – Ciph3rzer0 2009-09-28 12:59:24

+3

睡眠只停止你的線程。 – 2009-09-28 13:00:11

+3

對於讀取,寫入,異常參數,使用timeval和NULL作爲「select」。請注意,使用select這種方式只能在linux上運行,在windows中,如果僅提供timeval參數,select將立即返回 – laura 2009-09-28 13:03:00

3

考慮到你正在使用timespec,你的目標不是同步,而是等待,我建議睡眠。

#include <time.h> 

. 
. 
. 

    struct timespec remain; 
    remain.tv_sec = 5; 
    remain.tv_nsec = timeInMs * 1000; 

    do { 
    if (nanosleep(&remain, &remain) == 0 || errno != EINTR) { 
     break; 
    } 
    } while (1); 

. 
. 
. 
13

使用睡眠的任何變體,行爲不能保證。由於內核不知道不同的線程,所有線程也可以休眠。

使用更安全,更乾淨的解決方案是pthread_cond_timedwait。您錯誤地使用了API。這裏有一個更好的例子:

pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER; 

void mywait(int timeInMs) 
{ 
    struct timespec timeToWait; 
    struct timeval now; 
    int rt; 

    gettimeofday(&now,NULL); 


    timeToWait.tv_sec = now.tv_sec+5; 
    timeToWait.tv_nsec = (now.tv_usec+1000UL*timeInMs)*1000UL; 

    pthread_mutex_lock(&fakeMutex); 
    rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait); 
    pthread_mutex_unlock(&fakeMutex); 
    printf("\nDone\n"); 
} 

void* fun(void* arg) 
{ 
    printf("\nIn thread\n"); 
    mywait(1000); 
} 

int main() 
{ 
    pthread_t thread; 
    void *ret; 

    pthread_create(&thread, NULL, fun, NULL); 
    pthread_join(thread,&ret); 
} 

您需要指定多少時間,從目前的時間等待。既然你只告訴5秒和一些納秒,它發現時間已經過去,並沒有等待......如果有任何疑問,請讓我知道。

+0

對於我來說,gettimeofday(&now,NULL)不起作用,但是這樣做(對於200ms):\t clock_gettime(CLOCK_REALTIME ,&timeToWait); \t timeToWait.tv_nsec + = 200000000UL; \t timeToWait.tv_nsec%= 1000000000UL; \t timeToWait.tv_sec + = timeToWait.tv_nsec <200000000UL? 1:0; – 2017-08-02 15:46:55

11

pthread_cond_timedwait函數需要一個絕對時間,而不是相對時間。需要等待的時間,而不是等待多久。

1

這裏是一個例子,我從主循環中創建了一個線程,它掃描一個目錄並且超時時間爲5秒。而來自線程的信號發生使用一個全局的條件變量。我們一直從線程檢查此信號:

pthread_cond_t C_KISU_SwagntUtilityBase::m_cond; /*Global variable*/ 
/*Inside main function*/  
/*Local variables*/ 
      pthread_condattr_t l_attr; 
      pthread_condattr_init(&l_attr); 
      pthread_condattr_setclock(&l_attr, CLOCK_MONOTONIC); 
      pthread_cond_init(&C_KISU_SwagntUtilityBase::m_cond, &l_attr); 

      Int32 l_threadid = pthread_create(&l_updatethread,NULL,C_KISU_SwagntUtilityBase::ThreadScanDirectoryByFilter,&l_filer); 
      if(CMP_ZERO == l_threadid) 
      { 
      pthread_mutex_t l_mutex = PTHREAD_MUTEX_INITIALIZER; 
      struct timespec l_ts; 
      if (clock_gettime(CLOCK_MONOTONIC, &l_ts) == INIT_NEGONE) 
      { 
      /* Handle error */ 
      } 
      printf("\n Setting max time to run ThreadScanDirectoryByFilter as 5 second")); 
      l_ts.tv_sec += l_filer.m_max_scan_time; 

      if(l_filer.m_scan_status == 0) 
      { 
       pthread_mutex_lock(&l_mutex); 
       int l_rt = pthread_cond_timedwait(&C_KISU_SwagntUtilityBase::m_cond, &l_mutex, &l_ts); 
       if (ETIMEDOUT == l_rt) 
       { 
       printf("\n timeout has happened before scan routine could finish")); 
       } 
       else if (EOK == l_rt) 
       { 
       printf("\n Scan successful")); 
       } 
       else 
       { 
       printf("\n Unknown error while timeout condition check")); 
       } 
       pthread_mutex_unlock(&l_mutex); 
      } 
      } 
      else 
      { 
      printf("\n Error while creating thread\n"); 

      } 
9

那麼pthread_cond_timedwait使用絕對時間,所以需要:

  • 使用gettimeofday的檢索當前時間。
  • timespec.tv_nsec是納秒,它不能大於1秒。
  • timeval.tv_usec是微秒(1000納秒)。
  • timeInMs是毫秒:1毫秒= 1000微秒= 1000 * 1000納秒。

    void wait(int timeInMs) 
    { 
        struct timeval tv; 
        struct timespec ts; 
    
        gettimeofday(&tv, NULL); 
        ts.tv_sec = time(NULL) + timeInMs/1000; 
        ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeInMs % 1000); 
        ts.tv_sec += ts.tv_nsec/(1000 * 1000 * 1000); 
        ts.tv_nsec %= (1000 * 1000 * 1000); 
    
        n = pthread_cond_timedwait(&condition, &mutex, &ts); 
        if (n == 0) 
         // TODO: singaled 
        else if (n == ETIMEDOUT) 
         // TODO: Time out. 
    } 
    
相關問題