读者-写者问题
2016-01-20 19:58
253 查看
读者-写者问题为数据库访问建立了一个模型。
设想一个飞机订票系统,其中许多竞争的进程试图写其中的数据。多个进程同时读数据库是可以接受的,但如果一个进程正在更新(写)数据库,则所有其他进程都不能访问该数据库,即使读操作也不行。这里的问题是如何对读者和写者进行编程。
在该解法中,第一个读者对信号量db执行down操作。随后的读者只是递增一个计数器rc。当读者离开时,就递减这个计数器。最后一个读者离开时对信号量db执行up操作,这样就允许一个阻塞的写者访问该数据库。
有个问题:如果每2秒钟有一个读者进来,每个读者读5秒钟,这样写者就永远没有机会了。
可以稍微改变下程序写法:在一个读者到达,且一个写者在等待时,读者在写者之后被挂起,而不是允许立即进入。这种方案的缺点是并发度和效率比较低。
上面的效率较低,在读的过程中一直占用着资源。
设想一个飞机订票系统,其中许多竞争的进程试图写其中的数据。多个进程同时读数据库是可以接受的,但如果一个进程正在更新(写)数据库,则所有其他进程都不能访问该数据库,即使读操作也不行。这里的问题是如何对读者和写者进行编程。
在该解法中,第一个读者对信号量db执行down操作。随后的读者只是递增一个计数器rc。当读者离开时,就递减这个计数器。最后一个读者离开时对信号量db执行up操作,这样就允许一个阻塞的写者访问该数据库。
有个问题:如果每2秒钟有一个读者进来,每个读者读5秒钟,这样写者就永远没有机会了。
可以稍微改变下程序写法:在一个读者到达,且一个写者在等待时,读者在写者之后被挂起,而不是允许立即进入。这种方案的缺点是并发度和效率比较低。
#include <pthread.h> #include <stdio.h> #define READING_TIME 4 #define WRITTING_TIME 2 #define TIME_INTERVAL_READER 1 #define TIME_INTERVAL_WRITER 5 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER,db=PTHREAD_MUTEX_INITIALIZER; int rc=0; int count=0; void read_data_base(int i) { printf("第 %d 个读者在读\n", i); sleep(READING_TIME); printf("第 %d 个读者读完\n", i); } void write_data_base() { printf("正在写数据...\n"); sleep(WRITTING_TIME); } void* reader(void* arg) { while(1) { pthread_mutex_lock(&mutex); //获得对rc的访问权 rc=rc+1; count=count+1; if(rc==1) pthread_mutex_lock(&db); //第一个读者时,不让写者访问 pthread_mutex_unlock(&mutex); //释放对rc的访问权 read_data_base(count); //读数据 pthread_mutex_lock(&mutex); //获取对rc的访问权 rc=rc-1; if(rc==0) pthread_mutex_unlock(&db);//最后一个读者,释放db访问权 pthread_mutex_unlock(&mutex); sleep(TIME_INTERVAL_READER); } } void* writer(void* arg) { while(1) { sleep(TIME_INTERVAL_WRITER); pthread_mutex_lock(&db); //获得db访问 write_data_base(); //更新数据 pthread_mutex_unlock(&db); //释放访问权 } } int main() { pthread_t tid1,tid2; pthread_create(&tid1, NULL, reader,NULL); pthread_create(&tid2, NULL, writer,NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; }
上面的效率较低,在读的过程中一直占用着资源。
相关文章推荐
- 在jQuery,如何判断页面元素是否存在?
- 线程的私有数据
- [Java视频笔记]day02
- 多态之精华
- 【慕课笔记】第三章 常用的运算符 第7节 JAVA中运算符的优先级
- 开源JQuery框架 : Prime UI !
- git 常用命令
- 关于线程安全的笔记
- 使用wireshark观察SSL/TLS握手过程--双向认证/单向认证
- 開始要找工作喽!
- mbist summary
- python UnicodeDecodeError: 'ascii' codec can't decode byte 0xa6 in position 907: ordinal not in range(128)
- 什么是全角空格?什么是半角空格?
- TOP K
- Faster-RCNN+VGG用自己的数据集训练模型
- 图解SSL/TLS协议
- 博客如何使用百度打赏组件?
- 计算机视觉中常用数据集
- 实现二级列表(实现QQ的好友列表)
- vmware tools的复制粘贴失效