之前老是把读写者锁与生产者/消费者混淆,认为读写者是生产者/消费者的特例(当生产者个数为1时),后来才发现(也不知道现在的理解对不对:D),读写者模式中,多个读写可以同时读文件,而生产者/消费者模式中,消费者在消费时需要互斥。
读写者锁: 有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。
一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。
生产者/消费者
需要三个对象,互斥对象/事件/信号量/临界区对象: mutex,信号量:empty,full,分别表示空缓冲项和满缓冲项个数,emtpy初始化为为n,full初始化为0。伪代码如下:
生产者while(condition){ WaitForSingleObject(empty); Enter(mutex); //生产 Leave(mutex); ReleaseSemaphore(emtpy);}消费者while(condition2){ wait(full); wait(mutex); //消费 signal(mutex); signal(full);}
读写
三个对象,互斥对象/事件/信号量/临界区对象: mutex,wrt, int readcount. readcount初始化为0
写while(condition){ Enter(wrt); //写 Leave(wrt);}读while(condition2){ Enter(mutex); readcount++; if(1 == readcount) //多个读者可以一起读,因此,只要1个获得了读,其他也就获得了。 Enter(wrt); Leave(mutex); //读 Enter(mutex); readcount--; if(0 == readcount) //所有读者完成后,释放锁 Leave(wrt); Leave(mutex);}
MFC程序可以使用SRWLock来同步,C#程序则可以使用ReaderWriterLock来同步