信號量比互斥鎖高級,互斥鎖只容許一個線程訪問臨界區,信號量能夠多個,能夠把信號量看做成互斥鎖的升級版,可是若是能用互斥鎖解決,就用互斥鎖,互斥鎖比信號量節省資源。html
1,單個生產者和單個消費者c++
#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,多個生產者和多個消費者post
#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; }