多读者多写者

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多线程_(线程池,读者写者,自旋锁)

LINUX多线程(线程池,单例模式,线程安全,读者写者模型)

多线程面试题系列(14):读者写者问题继 读写锁SRWLock

Linux多线程_(线程池,单例模式,读者写者问题,自旋锁)

用C语言编程实现用信号量实现读者--写者问题(要源代码)