Linux多线程编程

发表于:2012-8-10 09:38

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:luxiaoxun    来源:51Testing软件测试网采编

  2)条件变量(cond)

  利用线程间共享的全局变量进行同步的一种机制。

int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);    
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,const timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond); 
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);  //解除所有线程的阻塞

  (1)初始化. init()或者pthread_cond_t cond=PTHREAD_COND_INITIALIER;属性置为NULL

  (2)等待条件成立. pthread_cond_wait,pthread_cond_timedwait.

  wait()释放锁,并阻塞等待条件变量为真

  timedwait()设置等待时间,仍未signal,返回ETIMEOUT(加锁保证只有一个线程wait)

  (3)激活条件变量:pthread_cond_signal,pthread_cond_broadcast(激活所有等待线程)

  (4)清除条件变量:destroy; 无线程等待,否则返回EBUSY

  int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
  int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);

  一定要在mutex的锁定区域内使用。

  调用 pthread_cond_signal() 释放被条件阻塞的线程时,如果没有任何线程基于条件变量阻塞,则调用pthread_cond_signal()不起作用。而对于 Windows,当调用 SetEvent 触发 Auto-reset 的 Event 条件时,如果没有被条件阻塞的线程,那么此函数仍然起作用,条件变量会处于触发状态。

  使用条件变量实现“生产者消费者问题”:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"pthread.h"

#define BUFFER_SIZE 16

struct prodcons
{
       int buffer[BUFFER_SIZE];
       pthread_mutex_t lock;  //mutex ensuring exclusive access to buffer
       int readpos,writepos;  //position for reading and writing
       pthread_cond_t notempty;  //signal when buffer is not empty
       pthread_cond_t notfull;  //signal when buffer is not full
};

//initialize a buffer
void init(struct prodcons* b)
{
     pthread_mutex_init(&b->lock,NULL);
     pthread_cond_init(&b->notempty,NULL);
     pthread_cond_init(&b->notfull,NULL);
     b->readpos=0;
     b->writepos=0;
}

//store an integer in the buffer
void put(struct prodcons* b, int data)
{
     pthread_mutex_lock(&b->lock);
     //wait until buffer is not full
     while((b->writepos+1)%BUFFER_SIZE==b->readpos)
     {
        printf("wait for not full\n");
        pthread_cond_wait(&b->notfull,&b->lock);
     }    
    
     b->buffer[b->writepos]=data;
     b->writepos++;
     pthread_cond_signal(&b->notempty); //signal buffer is not empty
     pthread_mutex_unlock(&b->lock);
}

//read and remove an integer from the buffer
int get(struct prodcons* b)
{
     int data;
     pthread_mutex_lock(&b->lock);
     //wait until buffer is not empty
     while(b->writepos==b->readpos)
     {
        printf("wait for not empty\n");
        pthread_cond_wait(&b->notempty,&b->lock);
     }    
    
     data=b->buffer[b->readpos];
     b->readpos++;
     if(b->readpos>=BUFFER_SIZE) b->readpos=0;
     pthread_cond_signal(&b->notfull);  //signal buffer is not full
     pthread_mutex_unlock(&b->lock);
     return data;
}

#define OVER -1

struct prodcons buffer;

void * producer(void * data)
{
     int n;
     for(n=0;n<1000;++n)
     {
       printf("put-->%d\n",n);
       put(&buffer,n);
     }
     put(&buffer,OVER);
     printf("producer stopped\n");
     return NULL;
}

void * consumer(void * data)
{
     int n;
     while(1)
     {
       int d=get(&buffer);
       if(d==OVER) break;
       printf("%d-->get\n",d);
     }
     printf("consumer stopped\n");
     return NULL;
}

int main()
{
    pthread_t tha,thb;
    void * retval;
   
    init(&buffer);
    pthread_creare(&tha,NULL,producer,0);
    pthread_creare(&thb,NULL,consumer,0);
   
    pthread_join(tha,&retval);
    pthread_join(thb,&retval);
   
    return 0;
}

54/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号