#include<pthread.h> #include<string.h> #include<stdlib.h> #include<stdio.h> #include<semaphore.h> typedef struct { int value; sem_t sem,semw;// 信號量要和共享資源相互"綁定" int sign; }Storage; void set_data(Storage *s,int value) { s->value=value; } int get_data(Storage* s) { return s->value; } void* rd1_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<100;i++) { sem_wait(&s->sem);//實現讀線程與寫線程的同步 s->sign++; int value=get_data(s); sleep(3); printf("rd1(0x)%lx read data :%d\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem);//實現讀線程之間的互斥 else sem_post(&s->semw);//實現寫線程與讀線程的同步 // usleep(100); sleep(4); } return (void*)0; } void* rd2_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<100;i++) { sem_wait(&s->sem); s->sign++; int value=get_data(s); sleep(2); printf("rd2(0x)%lx read data :%d\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else sem_post(&s->semw); // usleep(100); sleep(1); } return (void*)0; } void* rd3_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<100;i++) { sem_wait(&s->sem); s->sign++; int value=get_data(s); sleep(1); printf("rd3(0x)%lx read data :%d\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else sem_post(&s->semw); // usleep(100); sleep(2); } return (void*)0; } void* wt_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<100;i++) { sem_wait(&s->semw);//實現for循環里寫線程的互斥 s->sign=0; set_data(s,i+100); sleep(1); printf("wt(0x)%lx wrote data :%d\n",pthread_self(),i+100); sem_post(&s->sem);//實現寫線程與讀線程的同步 sleep(3); // sleep(5); } return (void*)0; } int main(void) { int err; pthread_t rd1,rd2,rd3,wt; Storage s; s.value=0; s.sign=0; sem_init(&s.sem,0,0);//初始化為0 sem_init(&s.semw,0,1);//初始化為1 pthread_create(&rd1,NULL,rd1_fn,(void*)&s); pthread_create(&rd2,NULL,rd2_fn,(void*)&s); pthread_create(&rd3,NULL,rd3_fn,(void*)&s); pthread_create(&wt,NULL,wt_fn,(void*)&s); pthread_join(rd1,NULL); pthread_join(rd2,NULL); pthread_join(rd3,NULL); pthread_join(wt,NULL); sem_destroy(&s.sem); sem_destroy(&s.semw); return 0; }
利用兩個信號量 實現了寫者之間的互斥,讀者之間的互斥,讀者和寫者之間的同步。 若要實現多個寫者,只需按照多個讀者的思路寫即可。