[Linux线程]线程的同步--使用条件变量完成线程同步

发布时间:2020-10-11 22:18:59 作者:银河星君
来源:网络 阅读:415
#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 4
#define OVER (-1)
struct producers                                        //定义生产者条件变量结构。
{
        int buffer[BUFFER_SIZE];                        //定义缓冲区。
        pthread_mutex_t lock;                           //定义访问缓冲区的互斥锁。
        int             readpos, writepos;                      //读写的位置。
        pthread_cond_t  notempty;                       //缓冲区有数据时的标记。
        pthread_cond_t  notfull;                        //缓冲区未满的标记。
};
//初始化缓冲区
void init(struct producers *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;
}
//在缓冲区中存放一个整数。
void put(struct producers *b, int data)
{
        pthread_mutex_lock(&b->lock);
        //当缓冲区为满时等待。
        while((b->writepos+1)%BUFFER_SIZE == b->readpos)
        {
          pthread_cond_wait(&b->notfull,&b->lock);
          //在返回之前,pthread_cond_wait需要参数b->lock。
        }
        //向缓冲区中写数据,并将写指针向前移动。
        b->buffer[b->writepos] = data;
        b->writepos++;
        if(b->writepos >= BUFFER_SIZE)
        {
         b->writepos=0;
        }
        //发送当前缓冲区中有数据的信号。
        pthread_cond_signal(&b->notempty);
        pthread_mutex_unlock(&b->lock);
}
//从缓冲区中读数据并将数据从缓冲区中移走。
int get(struct producers *b)
{
        int data;
        pthread_mutex_lock(&b->lock);
        //当缓冲区中有数据时等待。
        while(b->writepos == b->readpos)
        {
           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);
       pthread_mutex_unlock(&b->lock);
       return data;
}
struct producers  buffer;
//这是生产者的线程处理函数
void *producer(void *data)
{
    int n;
    for(n=0;n<10;n++)
    {
      printf("生产者: %d-->\n",n);  //连续10次生产
      put(&buffer,n);
    }
    put(&buffer,OVER);         //将状态放入buffer中
    return NULL;
}
//这是消费者的线程处理函数
void *consumer(void *data)
{
    int d;
    while(1)
    {
      d = get(&buffer);  //从buffer中读取对应的状态
      if(d == OVER)      //如果已经没有了则停止
      {
       break;
      }
      printf("消费者: --> %d\n",d);
    }
    return NULL;
}
//这是主程序
int main(int argc,char *argv[])
{
    pthread_t thproducer,thconsumer;    //生产者和消费者的id
    void *retval;
    init(&buffer);    //初始化缓冲区
    pthread_create(&thproducer,NULL,producer,0); 
    pthread_create(&thconsumer,NULL,consumer,0);  //创建两个线程
    pthread_join(thproducer,&retval);
    pthread_join(thconsumer,&retval);    //阻塞进程
    return 0;
}


推荐阅读:
  1. php实现big5转utf8的方法
  2. asp.net怎么得到GRIDVIEW中某行某列值的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

linux线程 --

上一篇:Pytest框架之fixture的详细使用教程

下一篇:C++实现猜数小游戏的实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》