信号量------线程的同步与互斥

我们前面介绍了线程的同步与互斥中的互斥锁与条件变量,接下俩我们实现线程的同步与互斥的下一个主题:信号量

我们在进程中也学习过信号量信号量—-进程间通信,那个信号量完全可以运用在线程通信上,且信号量是以集合的形式出现,我们实现线程间的互斥所用的信号量是以个数的形式出现,而且实现要比进程间通信的信号量简单的多。

信号量的函数接口:
信号量初始化
这里写图片描述
参数:
sem表示我们定义的信号量;
pshared为0,表示信号量用于同一个进程间的线程是同步的;
value表示的是可用资源的数量

信号量的销毁
这里写图片描述

信号量的P操作
这里写图片描述
上面的三个函数都可以获得锁资源,但若信号量的值为0,sem_wait将挂起等待,sem_trywait将非阻塞等待(先去做别的事情,一段时间过后再去看是否申请到锁)

信号量的V操作
这里写图片描述
使信号量的值加1,同时唤醒等待的线程

接下来我们运用信号量来重新实现生产者—-消费者模型,前面我们学习条件变量时时实现过,但缓冲区运用的是带头单链表来实现,我们今天运用“环形队列”来作为我们的缓冲区存放数据,环形队列用数组来实现。

一个生产者—一个消费者模型
分析:
1. 生产者要先与消费者
2. 当环形队列为空,必须保证生产者先运行(为空或则满由计数器决定)
3. 当环形队列为满时,必须保证消费者先运行

生产者关系的只有环形队列中格子都的个数,即blanks,消费者
关心的是环形队列中是否有有效的数据,,即datas,,所以我们设立两个信号量。
代码:

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>

#define SIZE 64

int buf[SIZE];
sem_t blanks,datas;

void* producter(void* arg){
    int i = 0;
    while(1){
        sem_wait(&blanks);
        int data = rand()%1234;
        buf[i] = data;
        printf("produce data is:%d\n",data);
        i++;
        i%=SIZE;
        sem_post(&datas);
    //  sleep(1);
    }
}
void* consumer(void* arg){
    int i = 0;
    while(1){
        sem_wait(&datas);
        int data = buf[i];
        printf("consumer data:%d\n",data);
        i++;
        i%=SIZE;
        sem_post(&blanks);
        sleep(1);
    }
}

int main()
{
    sem_init(&blanks,0,SIZE);
    sem_init(&datas,0,0);

    pthread_t id1,id2;
    pthread_create(&id1,NULL,producter,NULL);
    pthread_create(&id2,NULL,consumer,NULL);

    pthread_join(id1,NULL);
    pthread_join(id2,NULL);

    sem_destroy(&blanks);
    sem_destroy(&datas);

}

在linux下运行图片
这里写图片描述
这里写图片描述

当生产者产生数据慢,而消费者获取数据快的结果图为
这里写图片描述
可以看出,环形队列中,消费者绝对不会超过生产者

当生产者生产数据快,而消费者获取数据慢时结果图为
这里写图片描述

有结果图可以验证出,生产者当讲环形链表生产满数据后,不会再生产,等待消费者释放空格,生产者才能再次的生产数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值