信号量semaphore

信号量

头文件 - semaphore.h

信号量类型

	sem_t sem;------》本质int

相关函数

初始化信号量

sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
pshared:0 - 线程同步;1 - 进程同步。

value:最多有几个线程操作共享数据

销毁信号量

sem_destroy(sem_t *sem);

加锁

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

尝试加锁

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

限时尝试加锁

sem_timedwait(sem_t *sem, xxxxx);			

解锁

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

测试

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

测试源码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>


sem_t produce_sem;
sem_t custom_sem;

typedef struct node
{
    int data;
    struct node* next;
}Node;

Node* head = NULL;
// 操作套路:先对自己的做P操作,减少自己的,然后再对对方的做V操作,增加对方的。
void* producer(void* arg)
{
    while(1)
    {
        sem_wait(&produce_sem);     // porduce_sem --  == 0, 阻塞
        Node * node = (Node*)malloc(sizeof(Node));
        node->data = rand() % 1000;
        node->next = head;
        head = node;
        printf("+++++ 生产者:%lu, %d\n", pthread_self(), node->data);
        sem_post(&custom_sem);  // custom_sem++
        
        sleep(rand()%5);
    }

    return NULL;
}

void* customer(void* arg)
{
    while(1)
    {
        sem_wait(&custom_sem);
        Node* del = head;
        head = head->next;
        printf("----- 消费者:%lu, %d\n", pthread_self(), del->data);
        free(del);
        sem_post(&produce_sem);

        sleep(rand()%5);
    }
    return NULL;
}

int main(int argc, const char* argv[])
{
    pthread_t thid[2]; 

    // 初始化信号量
    sem_init(&produce_sem, 0, 4);   // 初始化生产者线程信号量
    sem_init(&custom_sem, 0, 0);    // 初始化消费者线程信号量

    pthread_create(&thid[0], NULL, producer, NULL);
    pthread_create(&thid[1], NULL, customer, NULL);

    for(int i=0; i<2; ++i)
    {
        pthread_join(thid[i], NULL);
    }

    sem_destroy(&produce_sem);
    sem_destroy(&custom_sem);

    return 0;
}

测试结果

在这里插入图片描述

关键代码分析

对比实际的交通信号灯,在一个十字路口,需要有2组信号量,首先是东西方向绿灯,南北方向红灯,东西方向的车可以通行。需要变灯的时候,需要先将东西方向自己的绿灯变成红灯,也就是set_wait(&self),然后再将南北方向的红灯变成绿灯,也就是set_post(&other)。

对应在代码下就是下面的样子:

sem_wait(&produce_sem); // porduce_sem – == 0, 阻塞
sem_post(&custom_sem); // custom_sem++,释放对方的
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值