多读者多写者
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多读者多写者相关的知识,希望对你有一定的参考价值。
这个代码实现功能是:有写者在写时其他的写者不能再写,当写者全部写完时,读者才能继续读,当读者全部读完时写者才能继续写,写者每个循环写一次,读者每个循环读一次。
#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,signw; }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<1000;i++) { sem_wait(&s->sem); s->sign++; int value=get_data(s); usleep(30000); printf("rd1(0x)%lx read data :%d\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(4); } return (void*)0; } void* rd2_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->sem); s->sign++; int value=get_data(s); usleep(30000); printf("rd2(0x)%lx read data :%d\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(1); } return (void*)0; } void* rd3_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->sem); s->sign++; int value=get_data(s); usleep(30000); printf("rd3(0x)%lx read data :%d\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(2); } return (void*)0; } void* wt_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->semw); s->sign=0; s->signw++; set_data(s,i+100); usleep(30000); printf("wt(0x)%lx wrote data :%d\\n",pthread_self(),i+100); if(s->signw!=2) sem_post(&s->semw); else sem_post(&s->sem); usleep(30000); // sleep(5); } return (void*)0; } void* wt_fn2(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->semw); s->sign=0; s->signw++; set_data(s,i+200); //sleep(30000); printf("wt2(0x)%lx wrote data :%d\\n",pthread_self(),i+200); if(s->signw!=2) sem_post(&s->semw); else sem_post(&s->sem); usleep(30000); // sleep(5); } return (void*)0; } int main(void) { int err; pthread_t rd1,rd2,rd3,wt1,wt2; Storage s; s.value=0; s.sign=0; s.signw=0; sem_init(&s.sem,0,0); sem_init(&s.semw,0,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(&wt1,NULL,wt_fn,(void*)&s); pthread_create(&wt2,NULL,wt_fn2,(void*)&s); pthread_join(rd1,NULL); pthread_join(rd2,NULL); pthread_join(rd3,NULL); pthread_join(wt1,NULL); pthread_join(wt2,NULL); sem_destroy(&s.sem); sem_destroy(&s.semw); return 0; }
这个是写一万个数据时CPU的占有率为%1
这个是写1000个数据时CPU的占有率,都是%1,与前者相同
改变写的数据的类型为字符串
#include<pthread.h> #include<string.h> #include<stdlib.h> #include<stdio.h> #include<semaphore.h> typedef struct { char* value; sem_t sem,semw; int sign,signw; }Storage; void set_data(Storage *s,char* value) { s->value=value; } char* get_data(Storage* s) { return s->value; } void* rd1_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->sem); s->sign++; char* value=get_data(s); usleep(30000); printf("rd1(0x)%lx read data :%s\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(4); } return (void*)0; } void* rd2_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->sem); s->sign++; char* value=get_data(s); usleep(30000); printf("rd2(0x)%lx read data :%s\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(1); } return (void*)0; } void* rd3_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->sem); s->sign++; char* value=get_data(s); usleep(30000); printf("rd3(0x)%lx read data :%s\\n",pthread_self(),value); if(s->sign!=3) sem_post(&s->sem); else { sem_post(&s->semw); s->signw=0; } usleep(30000); //sleep(2); } return (void*)0; } void* wt_fn(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->semw); s->sign=0; s->signw++; strcat(s->value,"abc"); //set_data(s,s->value); usleep(30000); printf("wt(0x)%lx wrote data :%s\\n",pthread_self(),s->value); if(s->signw!=2) sem_post(&s->semw); else sem_post(&s->sem); usleep(30000); // sleep(5); } return (void*)0; } void* wt_fn2(void *arg) { Storage *s=(Storage*)arg; int i=0; for(;i<1000;i++) { sem_wait(&s->semw); s->sign=0; s->signw++; strcat(s->value,"cba"); //set_data(s,i+200); //sleep(30000); printf("wt2(0x)%lx wrote data :%s\\n",pthread_self(),s->value); if(s->signw!=2) sem_post(&s->semw); else sem_post(&s->sem); usleep(30000); // sleep(5); } return (void*)0; } int main(void) { int err; pthread_t rd1,rd2,rd3,wt1,wt2; Storage s; s.value=(char*)malloc(sizeof(char)*2048); s.sign=0; s.signw=0; sem_init(&s.sem,0,0); sem_init(&s.semw,0,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(&wt1,NULL,wt_fn,(void*)&s); pthread_create(&wt2,NULL,wt_fn2,(void*)&s); pthread_join(rd1,NULL); pthread_join(rd2,NULL); pthread_join(rd3,NULL); pthread_join(wt1,NULL); pthread_join(wt2,NULL); sem_destroy(&s.sem); sem_destroy(&s.semw); return 0; }
程序运行时CPU占有率略有提高到%2
以上是关于多读者多写者的主要内容,如果未能解决你的问题,请参考以下文章
LINUX多线程(线程池,单例模式,线程安全,读者写者模型)
多线程面试题系列(14):读者写者问题继 读写锁SRWLock