我可以使用pthread_cond_wait(,)同时发信号通知多个线程吗?

时间:2019-01-16 20:37:38

标签: c multithreading signals

我正在编写各种代码段,看看会发生什么。下面的代码旨在将所有线程延迟到所有线程到达代码中的特定点,然后使每个线程打印一个唯一的数字。由于所有线程都这样做,所以数字应该以随机顺序出现。

我当前的问题是我让他们的线程忙于等待。如果线程数变大,程序将显着减慢速度。

我想通过使用信号来更改它,我为此找到了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; 
}

3 个答案:

答案 0 :(得分:2)

使用broadcast()

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

pthread_cond_broadcast()函数应解除阻塞当前在指定条件变量cond上阻塞的所有线程。

pthread_cond_signal()函数应解除阻塞至少一个在指定条件变量cond上阻塞的线程(如果在cond上阻塞了任何线程)。

答案 1 :(得分:0)

以下是... public class MyRedirectStrategy extends DefaultRedirectStrategy { ... @Override public boolean isRedirected( final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException { // check request and return true or false to redirect or not ... } } 的替代解决方案。

在创建其他线程之前,您定义一个读写互斥并将其锁定在主线程中处于写入状态。其他线程将尝试获取读锁定,但由于主线程具有写锁定,因此它们将被阻塞。

在创建所有线程之后,主线程释放锁。所有其他线程将被唤醒,并且由于许多读取锁可以共存,因此它们将同时执行(即,没有人将被锁定)。

代码可能类似于:

pthread_cond_broadcast()

答案 2 :(得分:-2)

尝试发布匹配的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