信号量解决生产者消费者问题

本文通过一个生产者消费者问题的案例,详细介绍了如何使用信号量实现线程间的同步和互斥。示例代码展示了如何初始化和操作信号量,以及如何在多线程环境下,通过p、v操作控制生产者和消费者的执行顺序,确保容器不会满溢或空置。
摘要由CSDN通过智能技术生成

生产者消费者问题:生产者不能在容器满了继续生成,消费者不能在容器为空的时候消费

1.信号量简介

用户进程可以通过操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。信号量是一个变量来表示系统中某种资源的数量。

原语:是一种特殊的程序段,其执行只能一气呵成,不可被中断。

p、v操作

p:

1.s-1

2. s-1>=0进程继续执行

3.s-1<0,进程阻塞进入等待队列,转进程调度

v

1.s+1

2.s+1>0进程继续执行

3.s+1<=0,则从该信号的等待队列中唤醒一等待进程,然后在返回原进程继续执行或转进程调度


2.信号量函数原型

sem_init

 int sem_init(sem_t *sem, int pshared, unsigned int value);

-功能:初始化信号量

-参数:

        -sem:信号量变量的地址

        -pshared:0用在线程间,非0用在进程间

        -value:信号量中的值

sem_destroy

int sem_destroy(sem_t *sem);

-功能:释放资源

sem_wait

 int sem_wait(sem_t *sem);

-功能:对信号量加锁,调用一次对信号量的值-1,如果值为0,就阻塞

sem_trywait/sem_timedwait

int sem_trywait(sem_t *sem);
-功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,不阻塞
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
-功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,等待设置的时间

sem_post

int sem_post(sem_t *sem);

功能:对信号量解锁,调用一次对信号量的值+1

3.案例源码

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

//创建一个互斥量
pthread_mutex_t mutex;
//创建两个信号量
sem_t psem;
sem_t csem;

struct Node{
    int num;
    struct Node *next;
};
struct Node *head;
void *producer(void *arg){
    //创建新的节点,添加到链表中
    while(1){
        sem_wait(&psem);
        pthread_mutex_lock(&mutex);
        struct Node * newNode = (struct Node*)malloc(sizeof(struct Node));
        newNode->next=head;
        head=newNode;
        newNode->num=rand()%1000;
        printf("add node, num %d,tid :%ld\n",newNode->num,pthread_self());
        pthread_mutex_unlock(&mutex);
        sem_post(&csem);
    }
}

void *customer(void *arg){
    while(1){
        sem_wait(&csem);
        pthread_mutex_lock(&mutex);
        struct Node *tmp=head;
        head=head->next;
        printf("del node, num:%d,tid:%ld\n",tmp->num,pthread_self());
        free(tmp);
        pthread_mutex_unlock(&mutex);
        sem_post(&psem);
    }
}
//头节点
struct Node * head = NULL;

int main(){
    pthread_mutex_init(&mutex,NULL);
    sem_init(&psem,0,8);
    sem_init(&csem,0,0);


    //创建五个生产者线程和五个消费者线程
    pthread_t ptids[5],ctids[5];
    for(int i=0;i<5;i++){
        pthread_create(&ptids[i],NULL,producer,NULL);
        pthread_create(&ctids[i],NULL,customer,NULL);
    }

    for(int i=0;i<5;i++){
        pthread_detach(ptids[i]);
        pthread_detach(ctids[i]);
    }

    while(1){
        sleep(10);
    }

    pthread_mutex_destroy(&mutex);
    sem_destroy(&psem);
    sem_destroy(&csem);
    pthread_exit(NULL);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值