C++学习笔记day35-----UC-信号量

在前一篇的笔记中,提到了使线程同步的两种方法,mutex锁和cond。
这里再介绍一种,信号量。
什么是信号量?
信号量是用于描述一个资源的可用数量。
假设我有10台电脑,这个时候电脑这个资源的信号量就是10。当我使用了一台电脑后, 信号量就会变成9。当时全部使用之后信号量就是0。这个时候如果还有人想要使用电脑就必须排队。
上述的例子可以抽象到线程中,当一个线程占有了一个资源,这个资源的信号量就会减一,信号量为0时,还有其他线程需要使用这个资源,就必须等待。
介绍一下信号量的函数:

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化一个匿名的信号量
参数:
sem:指定在这个地址上初始化一个匿名信号量
pshared:
0:一个进程的多个线程间共享这个信号量
not 0:多个进程间共享这个信号量
value:指定了信号量的初始值
返回值:
success:0
error:-1 errno被设置


#include <semaphore.h>
int sem_destroy(sem_t *sem);
功能:销毁一个信号量
参数:
sem:要销毁的信号量
返回值:
success:0
error:-1 errno被设置

#include <semaphore.h>
int sem_post(sem_t *sem);
功能:解锁一个信号量,将信号量的值加一,如果这个操作这后,信号量的值大于0,唤醒因为调用sem_wait而阻塞的线程,然后信号量被锁(-1);
参数:
sem:被操作的信号量
返回值:
success:0
error:-1 error被设置

#include <semaphore.h>
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
功能:锁住一个信号量,将信号量的值减一,如果信号量为0,则这个函数阻塞等待,直到信号量大于0,
参数:
sem:指定要操作的信号量
返回值:
success:0
error:-1 errno被设置

前一篇笔记中,使用线程间的同,步实现了消费者和生产者,但是没有考虑生产过量的情况。下面将使用信号量的方式控制生产者的生产。

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
//定义生产内容的结构体
typedef int queue_t[6];
queue_t q = {-1,-1,-1,-1,-1,-1};
sem_t p,c;
//生产程序
void *product(void *arg){
    int i = 0;
    //一直生产
    while(1){
        sem_wait(&p);
        q[i] = rand()%1000 + 1;
        printf("p:%d\n",q[i]);
        i = (i + 1) % 6;
        sem_post(&c);
        //随机等待
        sleep(rand()%5 + 1);
    }
}
//消费者执行程序
void *consume(void *arg){
    int j = 0;
    //一直消费
    while(1){
        sem_wait(&c);
        int tmp = q[j];
        q[j] = -1;
        j = (j + 1) % 6;
        printf("c:%d\n",tmp);
        sem_post(&p);
        sleep(rand()%5 + 1);
    }
}
int main(void){
    pthread_t pidone = 0,cid = 0;
    //初始化信号量
    sem_init(&p,0,6);
    sem_init(&c,0,0);
    //创建两个进程,一个用于生产者和消费者
    srand(time(NULL));
    pthread_create(&pidone,NULL,product,NULL);
    pthread_create(&cid,NULL,consume,NULL);
    //阻塞等待线程结束
    pthread_join(pidone,NULL);
    pthread_join(cid,NULL);
    sem_destroy(&p);
    sem_destroy(&c);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值