【Linux学习笔记】39:Linux下C模拟读者写者问题

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/SHU15121856/article/details/78417615

只开了一块缓冲区,所以不需要用mutex互斥信号量对其保护,直接交替PV操作就行了。应当找时间系统学习一下Linux下的C/C++编程,有很多有意思的功能。下面两个程序可以开两个terminal,编译好后,先执行生产者,再在另一个terminal里执行消费者的程序,然后在生产者的程序里输入(生产的)字符串就行了。因为用的是scanf的%s读入字符串,所以中间有空格时会陆续读入,这种时候观察两个进程的状态挺有意思。

生产者程序

#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/sem.h>

#define SEM_KEY 6666
#define true 1
#define false 0

//共用体
union semun {
    int setval;
    struct semid_ds *buf;
    unsigned short *array;
};

int main(int argc ,char *argv[])
{
    int shmid;//信号量的标识码ID,创建失败时为-1
    char *addr;//公用缓冲区(共享内存)首地址

    //shmget()创建一个共享内存,权限为0666
    shmid=shmget(ftok(".",1000),getpagesize(),IPC_CREAT  | 0666);
    //创建失败时为-1
    if(shmid==-1)
    {
       perror("shmget error:");
       exit(EXIT_FAILURE);
    }
    //输出共享内存的标识码ID
    printf("共享内存的标识码ID:=%d\n",shmid);


    //获取共享内存的起始地址,且为可读可写
    addr=shmat(shmid,0,0);
    //获取失败时为-1
    if(-1==*addr)
    {
       perror("shmat error:");
       exit(EXIT_FAILURE);
    }

    /*
    int semget(key_t _key,int _nsems,int _semflg);
    功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
    */
    //创建2个信号量的信号集
    int semid=semget(SEM_KEY, 2, IPC_CREAT | 0600);
    //创建失败时为-1
    if (-1 == semid)
    {
       perror("semget");
       exit(EXIT_FAILURE);
    }
    printf("信号集的标识码ID:=%d\n", semid);

    //初始化信号集
    union semun sem_args;
    unsigned short array[2]={0,1};
    sem_args.array = array;//赋值给共用体
    //SETALL代表设置信号集中所有的信号量的值。1,代表2个,sem_args是具体初始化的值放在共用体中
     int ret=semctl(semid, 1, SETALL, sem_args);
    //设置失败时为-1
    if (-1 == ret)
    {
       perror("semctl");
       exit(EXIT_FAILURE);
    }

    //对资源的使用处理操作
    /*
    struct sembuf{
     unsigned short sem_num;//第几个信号量,第一个信号量为0
     short sem_op;//对该信号量的操作(+/-)
     short sem_flg;//常被设置为SEM_UNDO,使得如果一个进程在没有释放信号量的情况下结束了执行,该进程掌握的信号量由系统自己释放
    };
    */
    struct sembuf P_full={0, -1, SEM_UNDO};
    struct sembuf V_full={0, +1, SEM_UNDO};
    struct sembuf P_empty={1, -1, SEM_UNDO};
    struct sembuf V_empty={1, +1, SEM_UNDO};

    printf("<这里是生产者进程,在这里输入生产出的字符串>\n");
    //不断生产
    while(true)
    {
        /*
        int semop(int semid ,struct sembuf *_sops ,size_t _nsops);
        功能:用户改变信号量的值。也就是使用资源还是释放资源使用权
        */
        semop(semid, &P_empty, 1);//P(empty)等待至空缓冲区数量不为0
        scanf("%s",addr);
        printf(">%s被读入了缓冲区\n",addr);
        semop(semid, &V_full, 1);//V(full)满缓冲区数量+1
        if(addr[0]=='@')
            break;//跳出循环,准备结束程序
    }
return 0;
}

消费者程序

#include<stdio.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<sys/sem.h>
#include<string.h>
#include<sys/stat.h>

#define SEM_KEY 6666
#define true 1
#define false 0

//共用体
union semun {
    int setval;
    struct semid_ds *buf;
    unsigned short *array;
};

int main(int argc ,char *argv[])
{

    int shmid;//信号量的标识码ID,创建失败时为-1
    char *addr;//公用缓冲区首地址

    //打开刚才原程序1创建的共享内存,权限为0666
    shmid= shmget(ftok(".",1000),getpagesize(), IPC_CREAT | 0666);

    printf("共享内存的标识码ID:=%d\n",shmid);

    //创建失败时为-1
    if(shmid==-1)
    {
       perror("shmget error:");
       exit(EXIT_FAILURE);
    }

    addr=shmat(shmid,0,0);//获取共享内存的起始地址,且为可读可写

    if(-1==*addr)
    {
       perror("shmat error:");
       exit(EXIT_FAILURE);
    }

    int semid=semget(SEM_KEY, 0, IPC_CREAT | 0600);//取得信号量

    if(-1==semid)
    {
       perror("semget");
       exit(EXIT_FAILURE);
    }

    printf("信号集的标识码ID:=%d\n", semid);

    //对资源的使用处理操作
    struct sembuf P_full={0, -1, SEM_UNDO};
    struct sembuf V_full={0, +1, SEM_UNDO};
    struct sembuf P_empty={1, -1, SEM_UNDO};
    struct sembuf V_empty={1, +1, SEM_UNDO};

    printf("<这里是消费者进程,不要在这里输入任何东西>\n");

    //不断消费
    while(true)
    {
        semop(semid, &P_full, 1);//P(full)等待至满缓冲区数量不为0
        //如果检测到生产者输入的第一个字符是@
        if(addr[0]=='@')
            break;//跳出循环,准备结束程序
        printf("消费ing...\n");
        sleep(3);//消费需要时间
        printf(">消费了");
        puts(addr);//输出这次消费的东西
        semop(semid, &V_empty, 1);//V(empty)空缓冲区数量+1
    }

    if(-1==semctl(semid,1,IPC_RMID,0))//删除信号量
    {
       perror("semctl error:");
       exit(EXIT_FAILURE);
    }

    if(-1==shmdt(addr))//释放共享内存,使其不再有任何指向它的指针
    {
       perror("shmdt error:");
       exit(EXIT_FAILURE);
    }

    if (shmctl(shmid,IPC_RMID,0)==-1)//删除共享内存
    {
       perror("shctl error:");
       exit(EXIT_FAILURE);
    }
return 0;
}

输入@符号就可以结束两个进程了,下面是运行的结果。
这里写图片描述
在做和进程有关的编程学习时,sleep()函数真的是一个非常好用的便于观察和思考的方法。

展开阅读全文

读者写者问题模拟出现java.lang.IllegalMonitorStateException异常

10-06

下面是对读者写者问题的模拟,但是运行时,总是出现java.lang.IllegalMonitorStateException异常。检查是notify和wait两个语句的问题。虽然将wait和notify都放在synchronized()中,可以消除异常,但是程序无法正常终止,似乎是出现了死锁。但是将wait不放在synchronized()中,虽然程序可以运行完成,但会出现上述异常。部分代码如下:rnrn[code=Java]class Writer extends Threadrn private Resource resource;rn private int id; //读者进程idrn rn public Writer(Resource resource, int id)rn this.id = id;rn this.resource = resource;rn rn rn public void run()rn rn tryrn resource.decreWmutex();rn if(resource.getWmutex() < 0) //如果wmutex已被某writer或reader进程占据,等待rn System.out.println("写进程" + this.id + "被阻塞!");rn rn wait(); rn elsern System.out.println("写进程" + this.id + "正在操作!");rn Thread.sleep(300);//正在访问时间rn rn rn catch(Exception e)rn e.printStackTrace();rn finallyrn resource.increWmutex();rn System.out.println("写进程" + this.id + "操作完毕!");rn synchronized(this)rn notifyAll();rn //notifyAll();rn rn rn rn rnrnrnclass Reader extends Threadrn rn private Resource resource;rn private int id;rn rn public Reader(Resource resource, int id)rn this.resource = resource;rn this.id = id;rn rn rn public void run()rn tryrn resource.decreRmutex();rn if(resource.getRmutex() < 0)rn System.out.println("读进程" + this.id + "被阻塞!未进入");rn rn wait(); rn rn elsern if(resource.getReadercount() == 0)//如果是0,判断有没有写进程在里面。rn resource.decreWmutex();rn if(resource.getWmutex() < 0)rn System.out.println("读进程" + this.id + "被阻塞!");rn rn wait(); rn rn rn resource.increReadercount(); //增加一个reader进程rn resource.increRmutex();//释放rmutex;rn System.out.println("读进程" + this.id + "进入!" + "当前进程数是" + resource.getReadercount());rn Thread.sleep(100);//模仿正在访问时间rn rn resource.decreRmutex();//重新访问rmutexrn if(resource.getRmutex() < 0)rn System.out.println("读进程" + this.id + "被阻塞!未出来");rn rn wait(); rn elsern resource.decreReadercount();rn if(resource.getReadercount() == 0) //如果,没有reader进程在里面,唤醒writer进程rn resource.increWmutex();rn rn rn catch(Exception e)rn e.printStackTrace();rn finallyrn resource.increRmutex();//释放rmutexrn System.out.println("读进程" + this.id + "操作完毕!" + "当前进程数是" + resource.getReadercount());rn rn //notifyAll();rn synchronized(this)rn notifyAll();rn rn rn rnrnrnpublic class RWProblem rn public static void main(String args[])rn Resource resource = new Resource();rn rn //定义2个写者进程rn for(int i = 0; i < 2; i++)rn Thread t = new Writer(resource, i);rn t.start();rn rn //定义5个读者进程rn for(int i = 0; i < 5; i++)rn Thread t = new Reader(resource, i);rn t.start();rn rn rnrn[/code]rnrn请各位帮我看看》》》 论坛

读者写者问题的错误

10-26

#include rn#include rn#include rn#include rn#include rn#include rn#include rn#include rn#include rn#define MAX_PERSON 100 //最多100人rn#define READER R //读者rn#define WRITER W //写者rn#define END -1 //结束rn#define R READERrn#define W WRITERrnrntypedef struct _Personrnrn rn int m_nType;//进程类型(读写)rn int m_nStartTime;//开始时间rn int m_nWorkTime;//运行时间rn int m_nID;//进程号rnPerson;rnPerson g_Persons[MAX_PERSON];rnHANDLE m_hThread[MAX_PERSON];//定义处理线程的句柄rnint g_NumPerson = 0;rnint g_NumOfReading = 0;//申请读进程的个数rnint g_NumOfWriteRequest = 0;//申请写进程的个数rnHANDLE g_hReadMutex;//读者信号rnHANDLE g_hWriteMutex;//写者信号rnDWORD WINAPI ReaderProc(void* p);rnDWORD WINAPI WriterProc(void* p);rnDWORD WINAPI ReaderProc(void* p)//读过程rnrn// wait for the start timern DWORD m_waitt;rn DWORD m_workt;rn int m_id; rn m_id=((Person *)(p))->m_nID;rn m_waitt=(DWORD)(((Person *)(p))->m_nStartTime*1000);rn m_workt=(DWORD)(((Person *)(p))->m_nWorkTime*1000);rn Sleep(1000);rn printf("Reader %d is Requesting ...\n",m_id);rn Sleep(m_waitt);rn printf("\n\n************************************************\n");rn WaitForSingleObject(g_hReadMutex,INFINITE);//等待g_hReadSemaphore读信号,即当g_hReadSemaphore有信号时等待结束 相当于p操作rn if(g_NumOfReading ==0)rn rn WaitForSingleObject(g_hWriteMutex,INFINITE); //当第一个读者到了,如果g_hWriteSemaphore信号灯灭了,说明有写者再写,读者必须等待。即互斥写操作rn rn g_NumOfReading++;rn ReleaseMutex(g_hReadMutex); //还有读者,但是允许下一个读进程读取,相当于V操作// modify the reader's real start timernrnrn //pPerson->m_nStartTime = g_CurrentTime; rn printf("Reader %d is Reading the Shared Buffer...\n",m_id);rn printf("\n\n************************************************\n"); rn Sleep(m_workt);rn //printf("Reader %d is Exit...\n",m_id);rn printf("\n\n************************************************\n");rn WaitForSingleObject(g_hReadMutex,INFINITE);rn printf("Reader %d is Exit...\n",m_id);rn g_NumOfReading--;rn printf("%d",g_NumOfReading);rn if(g_NumOfReading == 0) rn rn ReleaseMutex(g_hWriteMutex);//此时没有读者,可以写rn rn ReleaseMutex(g_hReadMutex);rnrn return 0;rnrnrnrnDWORD WINAPI WriterProc(void *p)rn rn DWORD m_waitt;rn DWORD m_workt;rn int m_id; rn m_id=((Person *)(p))->m_nID;rn m_waitt=(DWORD)(((Person *)(p))->m_nStartTime*1000);rn m_workt=(DWORD)(((Person *)(p))->m_nWorkTime*1000);rn Sleep(m_waitt);rn // wait for the start timern rn printf("Writer %d is Requesting ...\n",m_id);rn printf("\n\n************************************************\n"); rn //g_NumOfWriteRequest++;rn //在写者优先的时候需要用自加来初始信号值,而在读者优先的时是通过读者操作来控制信号值rn WaitForSingleObject(g_hWriteMutex,INFINITE);rn printf("Writer %d is Writting the Shared Buffer...\n",m_id);rn Sleep(m_workt);rn printf("Writer %d is Exit...\n",m_id);rn printf("\n\n************************************************\n");rn ReleaseMutex(g_hWriteMutex);rn return 0;rnrnrnrnrn rnrnrnrnvoid READFILE(char * file)rnrn int n = 0;rn DWORD thread_ID;rn DWORD wait_for_all;rn g_hReadMutex = CreateMutex(NULL,FALSE,NULL);//创建信号量,当前可用的资源数为1,最大为100 rn g_hWriteMutex = CreateMutex(NULL,FALSE,NULL);//创建信号量,当前可用的资源数为1,最大为100rn rn ifstream inFile;rn inFile.open(file);rn while(inFile)rn rn inFile>>g_Persons[n].m_nID;rn inFile>>g_Persons[n].m_nType;rn inFile>>g_Persons[n].m_nStartTime;rn inFile>>g_Persons[n].m_nWorkTime;rn n++;rn inFile.get();rn rn for(int i=0;i 论坛

读者-写者问题编程实现

06-07

自己写了一个简单的,不知道有没有错误,诚恳各位指点。rn[code=C/C++]rn#include rn#include rn//读者为主线程,写者为主线程创建的子线程rn//为读者优先策略rnDWORD WINAPI ThreadWriProc(rn LPVOID lpParameter // thread datarn);rnstatic HANDLE hThreadWri;rnstatic HANDLE hWriMutex;rnstatic HANDLE hCouMutex;rnint count=0;rnint main()rnrn //创建线程rn hThreadWri=CreateThread(NULL,0,ThreadWriProc,NULL,0,NULL);rn CloseHandle(hThreadWri);rn //创建互斥对象rn hWriMutex=CreateMutex(NULL,FALSE,"WriMutex");rn hCouMutex=CreateMutex(NULL,FALSE,"CouMutex");rn //读者程序执行主体rn while(TRUE)rn rn Sleep(8000);rn WaitForSingleObject(hCouMutex,INFINITE);rn ++count;rn if (1==count)rn rn WaitForSingleObject(hWriMutex,INFINITE);rn rn ReleaseMutex(hCouMutex);rn cout<<"读者正在读程序!"<rn#include rn#include rn#include "fstream.h"rn#include rn#include rn#include rnrn#define READER 'R'rn#define WRITER 'W'rn#define INTE_PER_SEC 100rn#define MAX_THREAD_NUM 64rn#define MAX_FILE_NUM 32rn#define MAX_STR_LEN 32rnrnrnint readcount=0;rnint writecount=0;rnCRITICAL_SECTION RP_Write;rnCRITICAL_SECTION WP_Read;rnCRITICAL_SECTION cs_Write;rnCRITICAL_SECTION cs_Read;rnrnrnstruct ThreadInforn int serial;rn char entity;rn double delay;rn double persist;rn;rnrnrnvoid ReaderPriority(char* file);rnvoid RP_ReaderThread(void *p);rnvoid RP_WriterThread(void *p);rnrnrnvoid WriterPriority(char* file);rnvoid WP_ReaderThread(void *p);rnvoid WP_WriterThread(void *p);rnrnrnrnrnint main()rnrn char ch;rn while(true)rn rn printf("********************************************\n");rn printf(" 1:Reader Priority \n");rn printf(" 2:Writer Priority \n");rn printf(" 3:Exit to Windows \n");rn printf("********************************************\n");rn printf("Enter your choice(1,2 or 3)\n");rn dorn rn ch=(char)_getch();rn while(ch!='1'&&ch!='2'&&ch!='3');rn system("cls");rn if(ch=='3')rn return 0;rn else if(ch=='1')rn ReaderPriority("thread.dat");rn elsern WriterPriority("thread.dat");rn printf("\nPress Any key to continue.\n");rn getch();rn system("cls");rn rn return 0;rnrnrnrnrnvoid ReaderPriority(char* file)rnrn DWORD n_thread=0;rn DWORD thread_ID;rn DWORD wait_for_all;rn HANDLE h_Mutex;rn h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_readcount");rn HANDLE h_Thread[MAX_THREAD_NUM];rn ThreadInfo thread_info[MAX_THREAD_NUM];rn readcount=0;rn InitializeCriticalSection(&RP_Write);rn ifstream inFile;rnrn inFile.open(file);rn printf("Reader Priority:\n\n");rn while (inFile)rn rn inFile>>thread_info[n_thread].serial;rn inFile>>thread_info[n_thread].entity;rn inFile>>thread_info[n_thread].delay;rn inFile>>thread_info[n_thread].persist;rn n_thread++;rn inFile.get();rn rn for(int i=0;i<(int)(n_thread);i++)rn rn if(thread_info[i].entity==READER||thread_info[i].entity=='r')rn h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&thread_info[i],0,&thread_ID);rn elsern h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&thread_info[i],0,&thread_ID);rn rn wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);rn printf("All Reader and Writer have finished operating.\n");rnrnrnrnvoid RP_ReaderThread(void *p)rnrn HANDLE h_Mutex;rn h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");rn DWORD wait_for_mutex;rn DWORD m_delay;rn DWORD m_persist;rn int m_serial;rn m_serial=((ThreadInfo *)(p))->serial;rn m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);rn m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);rn Sleep(m_delay);rn printf("Reader thread %d sents the reading require.\n",m_serial);rn wait_for_mutex=WaitForSingleObject(h_Mutex,-1);rn readcount++;rn if(readcount==1)rn EnterCriticalSection(&RP_Write);rn ReleaseMutex(h_Mutex);rn printf("Reader thread %d begins to read file.\n",m_serial);rn Sleep(m_persist);rn printf("Reader thread %d finished reading file.\n",m_serial);rn wait_for_mutex=WaitForSingleObject(h_Mutex,-1);rn readcount--;rn if(readcount==0)rn LeaveCriticalSection(&RP_Write);rn ReleaseMutex(h_Mutex);rnrnrnrnvoid RP_WriterThread(void *p)rnrn DWORD m_delay;rn DWORD m_persist;rn int m_serial;rn m_serial=((ThreadInfo *)(p))->serial;rn m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);rn m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);rn Sleep(m_delay);rn printf("Writer thread %d sents the Writing require.\n",m_serial);rn EnterCriticalSection(&RP_Write);rn printf("Writer thread %d begins to write file.\n",m_serial);rn Sleep(m_persist);rn printf("Writer thread %d finished writing file.\n",m_serial);rn LeaveCriticalSection(&RP_Write);rnrnrnrnvoid WriterPriority(char* file)rn DWORD n_thread=0;rn DWORD thread_ID;rn DWORD wait_for_all;rn HANDLE h_Mutex;rn h_Mutex=CreateMutex(NULL,FALSE,"mutex_for_writecount");rn HANDLE h_Thread[MAX_THREAD_NUM];rn ThreadInfo thread_info[MAX_THREAD_NUM];rn writecount=0;rn InitializeCriticalSection(&WP_Read);rn ifstream inFile;rn inFile.open(file);rn printf("Writer Priority:\n\n");rn while (inFile)rn rn inFile>>thread_info[n_thread].serial;rn inFile>>thread_info[n_thread].entity;rn inFile>>thread_info[n_thread].delay;rn inFile>>thread_info[n_thread].persist;rn n_thread++;rn inFile.get();rn rn for(int i=0;i<(int)(n_thread);i++)rn rn if(thread_info[i].entity==WRITER||thread_info[i].entity=='w')rn h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread),&thread_info[i],0,&thread_ID);rn elsern h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_info[i],0,&thread_ID);rnrn rn wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-1);rn printf("All Reader and Writer have finished operating.\n");rnrnrnvoid WP_WriterThread(void *p)rnrn HANDLE h_Mutex;rn h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_writecount");rn DWORD wait_for_mutex;rn DWORD m_delay;rn DWORD m_persist;rn int m_serial;rn m_serial=((ThreadInfo *)(p))->serial;rn m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);rn m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);rn Sleep(m_delay);rn printf("Writer thread %d sents the writing require.\n",m_serial);rn wait_for_mutex=WaitForSingleObject(h_Mutex,-1);rn writecount++;rn if(writecount==1)rn EnterCriticalSection(&WP_Read);rn ReleaseMutex(h_Mutex);rn printf("Writer thread %d begins to write file.\n",m_serial);rn Sleep(m_persist);rn printf("Writer thread %d finished writing file.\n",m_serial);rn wait_for_mutex=WaitForSingleObject(h_Mutex,-1);rn writecount--;rn if(writecount==0)rn LeaveCriticalSection(&WP_Read);rn ReleaseMutex(h_Mutex);rnrnrnrnvoid WP_ReaderThread(void *p)rnrn DWORD m_delay;rn DWORD m_persist;rn int m_serial;rn m_serial=((ThreadInfo *)(p))->serial;rn m_delay=(DWORD)(((ThreadInfo *)(p))->delay*INTE_PER_SEC);rn m_persist=(DWORD)(((ThreadInfo *)(p))->persist*INTE_PER_SEC);rn Sleep(m_delay);rn printf("Reader thread %d sents the Reading require.\n",m_serial);rn EnterCriticalSection(&WP_Read);rn printf("Reader thread %d begins to read file.\n",m_serial);rn Sleep(m_persist);rn printf("Reader thread %d finished reading file.\n",m_serial);rn LeaveCriticalSection(&WP_Read);rnrn[/code]rn各位也写点自己的多线程同步问题中的经典问题:读者-写者问题吧。 论坛

求教读者写者问题

11-02

正在做一个读者写者问题的作业,要求读者写者公平竞争,我用了队列模拟FIFO的已达到公平竞争,但是在运行时候一直提示队列为空,查了好久,发现我的endReading和endWriting方法在读写完之后均无调用,请问是什么原因?谢谢rn下面是我写的程序rnrn这个类是共用堆rn[code=java]rnimport java.util.Queue;rnrnrnpublic class Puffer rn private int readerCount;//读者数rn private int writerCount;//写者数rn private boolean dbReading;//读信号量rn private boolean dbWriting;//写信号量rn private Queue queue;rn rn public Puffer() rn readerCount=0;rn writerCount=0;rn dbReading=false;rn dbWriting=false;rn rn rn public synchronized int startRead(Reader r)//开始读rn while(writerCount>0)rn tryrn queue.add(r);rn System.out.println("reader is waiting");rn wait();//等待写者发出notifyrn rn catch(Exception e)rn rn rn readerCount++;rn if(readerCount==1)rn dbReading=true;rn rn return readerCount;rn rn rn public synchronized int endReading()//结束读rn --readerCount;rn System.out.println("endReading"+queue.size());rn rn if(readerCount==0&&queue.size()!=0)rn dbReading=false;rn rn for(Object o:queue)rn rn rn if(o.toString().equals("Reader"))rn rn notifyAll();rn queue.remove();rn elsern rn notifyAll();rn break;rn rn //没有读者rn rn rn rn //notifyAll();rn System.out.println("one reader is done reading. readerCount="+readerCount);rn return readerCount;rn rn public synchronized void startWriting(Writer w)//开始写rn ++writerCount;rn while(dbReading==true||dbWriting==true)rn tryrn queue.add(w);rn System.out.println("Writer "+writerCount+" is waiting");rn wait();//等待读者发出notifyrn rn catch(Exception e)rn rn rn rn dbWriting =true;rn rn rn public synchronized void endWriting()//结束写rn --writerCount;rn System.out.println("endWriting"+queue.size());rn if(writerCount==0&&queue.size()!=0)//没有写者rn dbWriting=false;rn rn for(Object o:queue)rn rn rn if(o.toString().equals("Reader"))rn rn queue.remove();rn notifyAll();rn elsern rn notifyAll();rn break;rn rn rn rn //System.out.println("one writer is done writing. writerCount="+writerCount);rn rn //notifyAll();rn rn rnrn[/code] 论坛

没有更多推荐了,返回首页