多线程同步之信号量

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

posted @ 2015-08-15 19:20  Sawyer Ford  阅读(455)  评论(0编辑  收藏  举报