0

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

我目前的问题是我让他们的线程忙于等待。如果线程数变大,程序会显着变慢。

我想通过使用信号来改变这一点,我发现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; 
}
4

3 回答 3

3

使用broadcast()

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

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

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

于 2019-01-16T20:41:35.170 回答
0

一个替代解决方案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; 
}
于 2019-01-18T09:40:45.267 回答
-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 释放线程等待结束

于 2019-01-16T20:45:39.193 回答