簡體   English   中英

我可以使用 pthread_cond_wait(,) 同時向多個線程發送信號嗎?

[英]Can I signal multiple threads simultaneously with pthread_cond_wait(,)?

我正在編寫各種代碼片段,看看會發生什么。 下面的代碼旨在延遲所有線程,直到所有線程都達到代碼中的某個點,然后使每個線程打印一個獨特的數字。 由於線程都這樣做,因此數字應該以隨機順序出現。

我目前的問題是我讓他們的線程忙於等待。 如果線程數變大,程序會顯着變慢。

我想通過使用信號來改變它,為此我找到了pthread_cond_wait() ,但是我不知道人們將如何使用它來向所有線程發出信號,要求他們醒來。

#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 

#define threads 10

int counter=0; 
pthread_mutex_t lock; 

void handler(void *v) {

    pthread_mutex_lock(&lock);  
    counter++;
    printf("%d\n", counter); 
    pthread_mutex_unlock(&lock);   
    while(counter != threads); // busy waiting

    printf("I am first! %d\n", v); 

}


int main() {

    pthread_t t[threads]; 
    for(int i =0; i < threads; i++) {       
    pthread_create(&t[i], NULL, handler, (void*) i); 
    }
    for(int i =0; i < threads; i++) {       
    pthread_join(t[i], NULL); 
    }

    return 0; 
}

編輯:我將代碼更改為以下內容,但是,它仍然不起作用:/

pthread_mutex_t lock; 
pthread_cond_t cv; 

void handler(void *v) {
    pthread_mutex_lock(&lock);
    pthread_cond_wait(&cv, &lock);
    printf("I am first! %d\n", v); 
    pthread_mutex_unlock(&lock);
}


int main() {
    pthread_t t[threads]; 
    for(int i =0; i < threads; i++) 
        pthread_create(&t[i], NULL, handler, (void*) i); 
        sleep(2); 
    pthread_cond_signal(&cv); 
    for(int i =0; i < threads; i++) 
        pthread_join(t[i], NULL); 
    return 0; 
}

使用broadcast()

http://pubs.opengroup.org/onlinepubs/009696699/functions/pthread_cond_broadcast.html

pthread_cond_broadcast()函數應解除當前在指定條件變量cond上阻塞的所有線程的阻塞。

pthread_cond_signal()函數應至少解除在指定條件變量cond上阻塞的線程之一(如果有任何線程在cond上阻塞)。

pthread_cond_broadcast()的替代解決方案可能如下。

在創建其他線程之前,您定義了一個讀寫互斥鎖並將其鎖定在主線程中的寫入中。 其他線程將嘗試獲取讀鎖,但由於主線程有寫鎖,它們將被阻塞。

創建所有線程后,主線程釋放鎖。 所有其他線程將被喚醒,並且由於許多讀鎖可以共存,因此將同時執行(即沒有人會被鎖定)。

代碼可能類似於:

pthread_rwlock_t lock; 

void handler(void *v) {
    if ((res = pthread_rwlock_rdlock(&lock)!=0)
    {
        exit(1);
    }
    printf("I am first! %d\n", v); 
    pthread_rwlock_unlock(&lock);
}


int main() {
    pthread_t t[threads];
    //First acquire the write lock:
    if ((res = pthread_rwlock_wrlock(&lock)!=0)
    {
        exit(1);
    }        
    for(int i =0; i < threads; i++)
    { 
        pthread_create(&t[i], NULL, handler, (void*) i); 
        //it is not clear if you want sleep inside the loop or not
        // You indented it as if to be inside but not put brackets
        sleep(2); 
    }
    pthread_rwlock_unlock(&lock); 
    for(int i =0; i < threads; i++) 
        pthread_join(t[i], NULL);
    pthread_rwlock_destroy(&lock);
    return 0; 
}

嘗試發布匹配的 remove_from_buffer 代碼。

更好的是,簡短的,自包含的,正確的示例 使用兩個線程制作一個簡短的 main()。 一個線程以隨機間隔添加到緩沖區。 另一個線程以隨機間隔從緩沖區中刪除。

例子

CELEBP22

/* CELEBP22 */                                   
#define _OPEN_THREADS                                                           
#include <pthread.h>                                                            
#include <stdio.h>                                                              
#include <time.h>                                                               
#include <unistd.h>                                                             

pthread_cond_t cond;                                                            
pthread_mutex_t mutex;                                                          

int footprint = 0;                                                              

void *thread(void *arg) {                                                       
  time_t T;                                                                     

  if (pthread_mutex_lock(&mutex) != 0) {                                        
    perror("pthread_mutex_lock() error");                                       
    exit(6);                                                                    
  }                                                                             
  time(&T);                                                                     
  printf("starting wait at %s", ctime(&T));                                     
  footprint++;                                                                  

  if (pthread_cond_wait(&cond, &mutex) != 0) {                                  
    perror("pthread_cond_timedwait() error");                                   
    exit(7);                                                                    
  }                                                                             
  time(&T);                                                                     
  printf("wait over at %s", ctime(&T));                                         
}                                                                               

main() {                                                                        
  pthread_t thid;                                                               
  time_t T;                                                                     
  struct timespec t;                                                            

  if (pthread_mutex_init(&mutex, NULL) != 0) {                                  
    perror("pthread_mutex_init() error");                                       
    exit(1);                                                                    
  }                                                                             

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

  if (pthread_create(&thid, NULL, thread, NULL) != 0) {                         
    perror("pthread_create() error");                                           
    exit(3);                                                                    
  }                                                                             

  while (footprint == 0)                                                        
    sleep(1);                                                                   

  puts("IPT is about ready to release the thread");                             
  sleep(2);                                                                     

  if (pthread_cond_signal(&cond) != 0) {                                        
    perror("pthread_cond_signal() error");                                      
    exit(4);                                                                    
  }                                                                             

  if (pthread_join(thid, NULL) != 0) {                                          
    perror("pthread_join() error");                                             
    exit(5);                                                                    
  }                                                                             
}       

輸出

2006 年 6 月 16 日星期五 10:54:06 開始等待 IPT 即將准備釋放線程等待 2006 年 6 月 16 日星期五 10:54:09 結束

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM