linux无名信号量通过线程实现生产者消费者模型

信号量

信号量是进化版的互斥锁,使用信号量可以并发的执行线程,使多个线程间对某一对象的部分数据进行共享,互斥锁只能串行的执行线程。
信号量可以通过不同线程来加锁和解锁。

信号量的相关函数

初始化信号量

sem_init(sem_t *sem,int pshared,unsigned int value);
0-线程同步
1-进程同步
value-最多有几个线程操作共享数据

销毁信号量

sem_destroy(sem_t *sem);

加锁

sem_wait(sem_t *sem);
调用一次相当于对sem做了一次 -- 操作
如果sem值为0,线程会阻塞

尝试加锁

sem_trywait(sem_t *sem);
sem == 0;加锁失败,不阻塞,直接发牛

限时尝试加锁

sem_timewait(sem_t *sem,xxxx);

解锁++

sem_post(sem_t *sem);
对sem做了++ 操作

练习

使用信号量实现生产者,消费者模型。

semxs.c

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

#define pvalue 3
#define cvalue 0

sem_t semp;
sem_t semc;
pthread_mutex_t mutex;
int num=0;//用来记录线程池的缓存数量

struct node * head=NULL;
struct node
{
        int data;
        struct node * next;
};
//生产者线程
void *producter(void * arc)
{
        while(1)
        {       //加锁,对pvalue信号量进行减操作
                sem_wait(&semp);
                 struct node *pr=(struct node *)malloc(sizeof(struct node));
                pr->data=rand()%1000;//产生随机数为0-999
                printf("producter pthread data is %d\n",pr->data);

                pthread_mutex_lock(&mutex);//互斥锁上锁 
                num++;
                pr->next=head;
                head=pr;
                printf("p num is %d\n",num);

                pthread_mutex_unlock(&mutex);//互斥所解锁
                sem_post(&semc);//解锁,对cvalue信号量进行加操作
                sleep(rand()%3);
        }
}
//消费者线程
void *customer(void * arc)
{
        while(1)
        {       sem_wait(&semc);//加锁,对cvalue信号量进行减操作
                pthread_mutex_lock(&mutex);
                num--;
                printf("v num is%d\n",num);
                struct node * cu=NULL;
                cu=head;
                head=cu->next;
                pthread_mutex_unlock(&mutex);
                printf("customer pthread data is %d\n",cu->data);
                sem_post(&semp);
                free(cu);
                cu=NULL;
                //sem_post(&semp);//解锁,对pvalue信号量进行加操作
                sleep(rand()%5);
        }
}

int main()
{

        pthread_t id1,id2;
        //生产者信号量初始化为3,表示线程池缓存大小为3
        sem_init(&semp,0,pvalue);
        //消费者信号量初始化为0,表示一开始不能消费
        sem_init(&semc,0,cvalue);

        pthread_create(&id1,NULL,producter,NULL);
        pthread_create(&id2,NULL,customer,NULL);

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

        pthread_mutex_destroy(&mutex);
        sem_destroy(&semc);
        sem_destroy(&semp);

        return 0;
}

请添加图片描述
设置semp为3和semc为0,这两个配合使用,使线程池的能够储存的数据最多为3个。当生产者生产数据,线程池累计数据,消费者消费线程池里的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值