APUE//线程同步3

2019-03-26  本文已影响0人  ustclcl

使用条件变量进行线程同步

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond;
                                   const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *restrict cond,
                                     pthread_mutex_t *restrict mutex,
                                     const struct timespec *restrict tsptr);
 // APUE example 11-15                             
 // using mutex and cond                           
 // lcl 20190326                                   
 //                                                
 #include "../myapue/h"                            
 #include <pthread.h>                              
                                                   
 struct msg{                                       
     struct msg * m_next;                          
     /* ...*/                                      
 };                                                
                                                   
 struct msg *workq;                                
 pthread_cond_t qready = PTHREAD_COND_INITIALIZER; 
 pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
                                                   
 void process_mag(void)                            
 {                                                 
     struct msg *mp;                               
     for(;;)                                       
     {                                             
         pthread_mutex_lock(&qlock);               
         while(workq == NULL)                      
           pthread_cond_wait(&qready, &qlock);     
         mp = workq;                               
         workq = mp -> m_next;                     
         phread_mutex_unlock(&qlock);              
         /* noe process msg */                     
     }                                             
 }                                                 
 void enqueue_msg(struct msg *mp)                  
 {                                                 
     pthread_mutex_lock(&qlock);                   
     mp->m_next = workq;                           
     workq = mp;                                   
     pthread_mutex_unlock(&qlock);                 
     pthread_cond_signal(&qready);                 
 }                                                 
                                                   

barrier,屏障

int pthread_barrier_init(pthread_barrier_t *restrict barrier,
            const pthread_barrierattr_t *restrict attr,      
            unsigned int count);                             
int pthrerd_barrier_destroy(pthread_barrier_t *barrier);     
int pthread_barrier_wait(pthread_barruer_t *barrier);        
/* APUE example 11-16                            
 * using barrier                                 
 * lcl 20190326                                  
 *                                               
 */                                              
                                                 
#include "../myapue.h"                           
#include <pthread.h>                             
#include <limits.h>                              
#include <sys/time.h>                            
                                                 
#define NTHR 8                                   
#define NUMNUM 8000000L                          
#define TNUM (NUMNUM/NTHR)                       
                                                 
long nums[NUMNUM];                               
long snums[NUMNUM];                              
                                                 
pthread_barrier_t b;                             
                                                 
//extern int qsort(void *, size_t, size_t,       
//          int (*)(const void*, const void *)); 
                                                 
int complong(const void *arg1, const void *arg2) 
{                                                
    long l1 = *(long *)arg1;                     
    long l2 = *(long *)arg2;                     
                                                 
    if (l1 == l2)                                
      return 0;                                  
    else if (l1 <l2)                             
        return -1;                               
    else return 1;                               
}                                                
                                                 
 void *thr_fn(void *arg)                         
{                                                
    long idx = (long)arg;                                       
                                                                
    qsort(&nums[idx], TNUM, sizeof(long), complong);            
    pthread_barrier_wait(&b);                                   
    return ((void*)0);                                          
}                                                               
                                                                
void merge()                                                    
{                                                               
    long idx[NTHR];                                             
    long i,minidx, sidx, num;                                   
                                                                
    for (i = 0;i<NTHR; i++)                                     
      idx[i] = i*TNUM;                                          
    for (sidx = 0;sidx < NUMNUM; sidx++){                       
        num = LONG_MAX;                                         
        for (i = 0; i<NTHR; i++){                               
            if( (idx[i] < (i+1)*TNUM) && (nums[idx[i]] < num)){ 
                num = nums[idx[i]];                             
                minidx = i;                                     
            }                                                   
        }                                                       
        snums[sidx] = nums[idx[minidx]];                        
        idx[minidx]++;                                          
    }                                                           
}                                                               
                                                                
int main()                                                      
{                                                               
    unsigned long i;                                            
    struct timeval start,end;                                   
    long long startusec, endusec;                               
    double elapsed;                                             
    int err;                                                    
    pthread_t tid;                                              
                                                                
    // create the initial set of numbers to sort.               
    srandom(1);                                                 
    for(i=0; i<NUMNUM; i++) {                                   
        nums[i] = random();                                     
    }                                                           
                                                                
    // create 8 threads to sort the numbers                     
    gettimeofday(&start,NULL);                                  
    pthread_barrier_init(&b, NULL, NTHR+1);                     
    for (i=0; i<NTHR; i++)                                      
    {                                                           
        err = pthread_create(&tid,NULL,thr_fn,(void *)(i*TNUM));
        if(err!=0)                                              
          printf("can't create thread");                        
    }                                                           
    pthread_barrier_wait(&b);                                   
    merge();                                                    
    gettimeofday(&end,NULL);                                    
                                                                
    startusec = start.tv_sec * 1000000 + start.tv_usec;         
                                                                
    endusec = end.tv_sec * 1000000 + end.tv_usec;               
    elapsed = (double)(endusec - startusec)/1000000.0;          
    printf("sort using %.4f seconds\n",elapsed);                
    for(i=0;i<100;i++)                                          
      printf("%ld\n",snums[i]);                                 
    exit(0);                                                    
}                                                               
上一篇 下一篇

猜你喜欢

热点阅读