Linux 信号量之Posix基于内存的信号量
Posted xiaoshiwang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 信号量之Posix基于内存的信号量相关的知识,希望对你有一定的参考价值。
信号量(semaphore),也和互斥锁一样提供了线程间或者进程间的同步功能。
信号量有三种:
- Posix有名字的信号量
- Posix基于内存的信号量
- System V信号量
信号量比互斥锁高级,互斥锁只允许一个线程访问临界区,信号量可以多个,可以把信号量看作成互斥锁的升级版,但是如果能用互斥锁解决,就用互斥锁,互斥锁比信号量节省资源。
这篇文章只介绍Posix基于内存的信号量
1,单个生产者和单个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
int nitems;
struct
int buff[NBUFF];
sem_t mutex, nempty, nstored;
shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv)
pthread_t tid_produce, tid_consume;
if(argc != 2)
printf("usage error\\n");
exit(1);
nitems = atoi(argv[1]);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
pthread_create(&tid_produce, NULL, produce, NULL);
pthread_create(&tid_consume, NULL, consume, NULL);
pthread_join(tid_produce, NULL);
pthread_join(tid_consume, NULL);
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
void* produce(void *args)
int i;
for(i = 0; i < nitems; ++i)
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
shared.buff[i % NBUFF] = i;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
return NULL;
void* consume(void* args)
int i;
for(i = 0; i < nitems; ++i)
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
shared.buff[i % NBUFF] = i;
sem_post(&shared.mutex);
sem_post(&shared.nempty);
return NULL;
2,多个生产者和单个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
#define MAXTHRS 100
#define min(x,y) ( x > y ? y:x )
int nitems, nproducers;
struct
int buff[NBUFF];
int idx;
int val;
sem_t mutex, nempty, nstored;
shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv)
int i, count[MAXTHRS];
pthread_t tid_produce[MAXTHRS], tid_consume;
if(argc != 3)
printf("usage error\\n");
exit(1);
nitems = atoi(argv[1]);
nproducers = min(atoi(argv[2]), MAXTHRS);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
for(i = 0; i < nproducers; ++i)
count[i] = 0;
pthread_create(&tid_produce[i], NULL, produce, &count[i]);
pthread_create(&tid_consume, NULL, consume, NULL);
for(i = 0; i < nproducers; ++i)
pthread_join(tid_produce[i], NULL);
printf("count[%d] = %d\\n", i, count[i]);
pthread_join(tid_consume, NULL);
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
void* produce(void *arg)
int i;
for(i = 0; i < nitems; ++i)
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
if(shared.idx >= nitems)
sem_post(&shared.nempty);//注意点
sem_post(&shared.mutex);
return NULL;// all done
shared.buff[shared.idx % NBUFF] = shared.val;
shared.idx++;
shared.val++;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
*((int*) arg) += 1;
return NULL;
void* consume(void* args)
int i;
for(i = 0; i < nitems; ++i)
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
if(shared.buff[i % NBUFF] != i)
printf("error:buff[%d] = %d\\n", i, shared.buff[i % NBUFF]);
sem_post(&shared.mutex);
sem_post(&shared.nempty);
return NULL;
3,多个生产者和多个消费者
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#define NBUFF 10
#define MAXTHRS 100
#define min(x,y) ( x > y ? y:x )
int nitems, nproducers, nconsumers;
struct
int buff[NBUFF];
int idx;
int val;
int gidx;
int gval;
sem_t mutex, nempty, nstored;
shared;
void* produce(void *args);
void* consume(void* args);
int main(int argc, char** argv)
int i, prodcount[MAXTHRS], conscount[MAXTHRS];
pthread_t tid_produce[MAXTHRS], tid_consume[MAXTHRS];
if(argc != 4)
printf("usage error\\n");
exit(1);
nitems = atoi(argv[1]);
nproducers = min(atoi(argv[2]), MAXTHRS);
nconsumers = min(atoi(argv[3]), MAXTHRS);
//create 3 semaphore
sem_init(&shared.mutex, 0, 1);
sem_init(&shared.nempty, 0, NBUFF);
sem_init(&shared.nstored, 0, 0);
for(i = 0; i < nproducers; ++i)
prodcount[i] = 0;
pthread_create(&tid_produce[i], NULL, produce, &prodcount[i]);
for(i = 0; i < nconsumers; ++i)
conscount[i] = 0;
pthread_create(&tid_consume[i], NULL, consume, &conscount[i]);
for(i = 0; i < nproducers; ++i)
pthread_join(tid_produce[i], NULL);
printf("prodcount[%d] = %d\\n", i, prodcount[i]);
for(i = 0; i < nconsumers; ++i)
pthread_join(tid_consume[i], NULL);
printf("conscount[%d] = %d\\n", i, conscount[i]);
sem_destroy(&shared.mutex);
sem_destroy(&shared.nempty);
sem_destroy(&shared.nstored);
exit(0);
void* produce(void *arg)
int i;
for(i = 0; i < nitems; ++i)
sem_wait(&shared.nempty);
sem_wait(&shared.mutex);
if(shared.idx >= nitems)
sem_post(&shared.nstored);//注意点
sem_post(&shared.nempty);//注意点
sem_post(&shared.mutex);
return NULL;// all done
shared.buff[shared.idx % NBUFF] = shared.val;
shared.idx++;
shared.val++;
sem_post(&shared.mutex);
sem_post(&shared.nstored);
*((int*) arg) += 1;
return NULL;
void* consume(void* arg)
int i;
for(; ;)
sem_wait(&shared.nstored);
sem_wait(&shared.mutex);
if(shared.gidx >= nitems)
sem_post(&shared.nstored);//注意点
sem_post(&shared.mutex);
return NULL;// all done
i = shared.gidx % NBUFF;
if(shared.buff[i] != shared.gval)
printf("error:buff[%d] = %d\\n", i, shared.buff[i]);
shared.gidx++;
shared.gval++;
sem_post(&shared.mutex);
sem_post(&shared.nempty);
*((int*) arg) += 1;
return NULL;
c/c++ 学习互助QQ群:877684253
本人微信:xiaoshitou5854
以上是关于Linux 信号量之Posix基于内存的信号量的主要内容,如果未能解决你的问题,请参考以下文章