多读者多写者

这个代码实现功能是:有写者在写时其他的写者不能再写,当写者全部写完时,读者才能继续读,当读者全部读完时写者才能继续写,写者每个循环写一次,读者每个循环读一次。#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

时间: 2024-10-13 00:56:28

多读者多写者的相关文章

读者与写者问题

***********************************************声明****************************************************** 原创作品,出自 "晓风残月xj" 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj). 由于各种原因,可能存在诸多不足,欢迎斧正! *******************************************

Java 实现读者与写者

1 package r_d; 2 /** 3 * 以下读者与写者实验以swing为主要实现 4 */ 5 import java.awt.*; 6 import javax.swing.*; 7 import javax.swing.border.TitledBorder; 8 9 import java.awt.event.*; 10 import java.util.Random; 11 import java.util.concurrent.Semaphore; 12 import jav

读者与写者、生产者与消费者

1.读者写者 写者:写数据 读者:仅仅是读数据,不存在取走数据 写者与写者关系:互斥 读者与读者关系:没有关系 写者与读者关系:同步.互斥 解决方法: 1)读者优先:读者正在读,写者不能终止读者,直到读者读完,写者才能写入 2)写者优先:写者正在写,读者不能终止写者,直到写者写完,读者才能写入 2.生产者消费者 生产者:产生数据 消费者:取走数据 生产者与生产者:互斥关系 消费者与消费者:互斥关系 生产者与消费者:互斥.同步关系 生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与

进程同步——读者、写者问题

一个数据文件可以被多个进程所共享,把只要求读文件的进程成为“Reader进程”,其他进程称为“Writer进程”,允许多个进程读,但是不允许一个Writer进程和其他进程一起读或者写. 读者: 在读者问题中,把readcount当成了互斥信号量,在执行readcount减减或加加之前都要指向p操作. semaphore rmutex=1,wmutex=1; //rmutex信号量保证多个Reader进程对互斥资源的访问,这里把readcount当作了互斥资源 //wmutex信号量保证读写进程的

读者写者模型

编写多线程时有些共享的数据需要修改的机会少而读的机会多,在读的过程中消耗的时间较长,因在读的时候先要查找,因此加入读写锁对代码的访问较快,还很好的对代码块进行了加锁.读写锁实际是基于自旋锁的(当线程访问某资源条件不满足时,不挂起该线程,而是让它一直重复rwlock_trylock,适用于在锁中待得时间较短) 它也有三种关系(读者与读者之间无关系,写着与写着之间互斥,读者与写着之间同步.互斥),两个角色(读者.写着),一个场所 需要考虑读者与写着之间的优先级,避免读者一直读,而写着一直阻塞等待,没

Linux多线程实践(6) --Posix读写锁解决读者写者问题

Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthre

秒杀多线程第十一篇 读者写者问题

与上一篇<秒杀多线程第十篇 生产者消费者问题>的生产者消费者问题一样,读者写者也是一个非常著名的同步问题.读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件. 上面是读者写者问题示意图,类似于生产者消费者问题的分析过程,首先来找找哪些是属于“等待”情况. 第一.写者要等到没有读者时才能去写文件. 第二.所有读者要等待写者完成写文件后才能去读文件. 找完“等待”情况后,再看看有没有要互斥访问的资源.由

使用读写锁解决读者-写者问题

读写锁 读写锁适合于对数据结构的读次数比写次数多得多的情况.因为,读模式锁定时可以共享,以写 模式锁住时意味着独占,所以读写锁又叫共享-独占锁. 初始化和销毁: #include <pthread.h> int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t

读者写者问题

为什么会有自旋锁 在编写多线程的时候,有些公共数据读的概率远远大于修改的几率.通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长.给这种代码段加锁,会极大地降低我们程序的效率.我们引入了读写锁即自旋锁处理这种多读少写的情况. 2.什么是自旋锁 (1)它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作. (2)这种锁相对于自旋锁而言,能提高并发性. (3)在多处理器系统中: a.对于读者:它允许同时有多个读者来访问共享资源,最大可能的读者数为