• 多线程同步之信号量


        信号量是什么?简单来说,信号量就是一个计数值,假设记为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多线程】三个经典同步问题

  • 相关阅读:
    ES6/5比较
    Javascript中的var和let
    git中remotes/origin/HEAD指向的分支丢失
    js实用篇之数组、字符串常用方法
    JS设计模式一:单例模式
    Linux C 面试题总结 .
    深入理解javascript原型和闭包(15)——闭包
    一些有意思的面试题(持续更新) .C语言编程技巧札记
    一个三流大学生的北京三年 .
    C 字节对齐.我的算法学习之路
  • 原文地址:https://www.cnblogs.com/gattaca/p/4732968.html
Copyright © 2020-2023  润新知