zoukankan      html  css  js  c++  java
  • 多线程同步之信号量

        信号量是什么?简单来说,信号量就是一个计数值,假设记为S。S > 0时,表示当前可用资源的数目;S < 0时,其绝对值表示等待使用该资源的进程个数。信号量可作为一种同步手段控制多个进程对资源的访问。

       可以通过PV操作改变信号量的值。

    P操作:

    S = S -1;
    if S >= 0
        continue;
    else
        blocked;

    V操作:

    S = S + 1;
    if S > 0
        continue;
    else
        wakeup a blocked process;

        信号量的经典应用当属“生产者-消费者”问题。生产者-消费者问题(producer-consumer problem)又被称为有限缓冲问题(bounded-buffer problem)。存在一个固定大小的缓冲区,生产者进程向缓冲区中存放数据,消费者进程从缓冲区中取走数据。但是缓冲区满时,生产者不能向其中存放数据;缓冲区空时,消费者不能从缓冲区中取走数据。信号量是这一问题的常见解决方案。

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <semaphore.h>
    #define bufferSize 5
    #define N 10        //number of producer
    int buffer[bufferSize];
    sem_t mutex;
    sem_t empty;
    sem_t full;
    int i = 0;
    int j = 0;
    
    void* produce(void *arg)
    {
        while (1)
        {
            sem_wait(&empty);
            sem_wait(&mutex);
    
            buffer[i] = 10 + rand() %90;
            printf("Producer %d write Buffer[%d]: %d
    ", arg, i, buffer[i]);
            i = (i+1) % bufferSize;
    
            sem_post(&mutex);
            sem_post(&full);
        }
    }
    
    void* consume(void *arg)
    {
        while (1)
        {
            sem_wait(&full);
            sem_wait(&mutex);
    
            printf("Consumer %d read Buffer[%d]: %d
    ", arg, j, buffer[j]);
            j = (j+1) % bufferSize;
    
            sem_post(&mutex);
            sem_post(&empty);
    } }
    int main() { sem_init(&mutex, 0, 1); sem_init(&empty, 0, bufferSize); sem_init(&full, 0, 0); pthread_t producers[N]; pthread_t consumers[N]; int i; for (i = 0; i < N; ++i) { pthread_create(&producers[i], NULL, produce, (void*)i); pthread_create(&consumers[i], NULL, consume, (void*)i); } sleep(1); sem_destroy(&mutex); sem_destroy(&empty); sem_destroy(&full); return 0; }

    用到的函数有:

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

    REFERENCE:

    【Linux多线程】三个经典同步问题

  • 相关阅读:
    spring boot项目接入xxl-job
    Vue3 目录结构
    [原创]阿里全链路压测学习及理解
    python测试开发django-107.form组件widgets(radio/checkbox/单选多选下拉框/日历控件)
    ubuntu通过nginx部署fastcgi程序
    fastcgi
    fpc protobuf开源框架
    delphi jwt
    JWT
    google protobuf经验
  • 原文地址:https://www.cnblogs.com/gattaca/p/4732968.html
Copyright © 2011-2022 走看看