读者写者和生产者消费者

读者写者问题

假设两个线程:读者线程,写者线程

读者写者问题是这样一种情况,就是允许对支援进行两种类型的操作(读和写)。

其中写操作是排他的(排斥读者,同样排斥其他写者),读操作是共享的(多个读者可以读,但是排斥其他写者)。

具体是指:读者写者问题,是指保证一个writer进程必须与其他进程互斥地访问共享对象的同步问题。读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本

书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。当读者提出请

求时需要有一个互斥操作,另外,需要有一个信号量S来当前是否可操作。

对于读者-写者,一班有三种解决方法:

(1)读者优先

读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导

致写者长时间等待,甚至有可能出现写者被饿死的情况。

(2)写者优先

写者优先的规定,即当有读者和写者同时等待时,首先满足写者。当一个写者声明想写文件时,不允许新的读者再访问文件。

(3)无优先

谁先等待谁就先使用文。


生产者消费者问题

生产者消费者问题,也称有限缓冲问题,是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时

会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓

冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。同样, 

也可以让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者。通常采用进程间通信的方法解决该问题。如果解决办法不够完善,则容易出现死

锁的情况。出现死锁时,两个线程都会陷入休眠,等待对方唤醒自己。该问题也能被推广到多个生产者和消费者的情形。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者-消费者问题一个经典并发问题,描述了两个进程(或线程)之间的同步和通信问题。生产者进程负责生产一些物品并将它们放入一个缓冲区中,而消费者进程则从缓冲区中取出物品并将其消耗掉。该问题的关键在于确保生产者和消费者不会同时访问缓冲区,以免出现竞态条件和数据不一致的问题。 以下是一个使用信号量来解决生产者-消费者问题的示例代码: ```c++ #include <cstdio> #include <cstdlib> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; // 缓冲区 int in = 0; // 生产者放置产品的位置 int out = 0; // 消费者取产品的位置 sem_t empty; // 同步信号量,表示缓冲区中空闲位置的数量 sem_t full; // 同步信号量,表示缓冲区中已有产品的数量 pthread_mutex_t mutex; // 互斥锁,保护对缓冲区的访问 void *producer(void *arg) { for (int i = 0; i < 100; i++) { sem_wait(&empty); pthread_mutex_lock(&mutex); buffer[in] = rand() % 100; printf("Producer produces item %d: %d\n", in, buffer[in]); in = (in + 1) % BUFFER_SIZE; pthread_mutex_unlock(&mutex); sem_post(&full); } } void *consumer(void *arg) { for (int i = 0; i < 100; i++) { sem_wait(&full); pthread_mutex_lock(&mutex); int item = buffer[out]; printf("Consumer consumes item %d: %d\n", out, item); out = (out + 1) % BUFFER_SIZE; pthread_mutex_unlock(&mutex); sem_post(&empty); } } int main() { sem_init(&empty, 0, BUFFER_SIZE); // 初始化 empty 为 BUFFER_SIZE sem_init(&full, 0, 0); // 初始化 full 为 0 pthread_mutex_init(&mutex, NULL); // 初始化互斥锁 pthread_t producer_thread, consumer_thread; pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); sem_destroy(&empty); sem_destroy(&full); pthread_mutex_destroy(&mutex); return 0; } ``` 读者-写者问题也是一个经典并发问题,描述了多个进程(或线程)之间共享一个资源的情况。在读者-写者问题中,资源可以被多个读者同时访问,但只能由一个写者访问。如果一个写者正在访问资源,那么其他所有的读者写者都必须等待。如果一个读者正在访问资源,那么其他的读者可以同时访问,但写者必须等待所有的读者都访问完毕后才能访问。 以下是一个使用互斥锁和条件变量来解决读者-写者问题的示例代码: ```c++ #include <cstdio> #include <cstdlib> #include <pthread.h> #define READERS_COUNT 5 #define WRITERS_COUNT 3 int read_count = 0; // 当前正在读取资源的读者数量 int resource = 0; // 被读取和写入的共享资源 pthread_mutex_t read_mutex; // 保护 read_count 的互斥锁 pthread_mutex_t write_mutex; // 保护 resource 的互斥锁 pthread_cond_t write_cond; // 写者等待的条件变量 pthread_cond_t read_cond; // 读者等待的条件变量 void *reader(void *arg) { int id = *(int *) arg; while (true) { pthread_mutex_lock(&read_mutex); read_count++; if (read_count == 1) { pthread_mutex_lock(&write_mutex); } pthread_mutex_unlock(&read_mutex); printf("Reader %d reads resource: %d\n", id, resource); pthread_mutex_lock(&read_mutex); read_count--; if (read_count == 0) { pthread_mutex_unlock(&write_mutex); } pthread_mutex_unlock(&read_mutex); sleep(rand() % 3); } } void *writer(void *arg) { int id = *(int *) arg; while (true) { pthread_mutex_lock(&write_mutex); while (read_count > 0) { pthread_cond_wait(&write_cond, &write_mutex); } resource = rand() % 100; printf("Writer %d writes resource: %d\n", id, resource); pthread_cond_broadcast(&read_cond); pthread_mutex_unlock(&write_mutex); sleep(rand() % 3); } } int main() { pthread_mutex_init(&read_mutex, NULL); pthread_mutex_init(&write_mutex, NULL); pthread_cond_init(&read_cond, NULL); pthread_cond_init(&write_cond, NULL); pthread_t readers[READERS_COUNT], writers[WRITERS_COUNT]; int reader_ids[READERS_COUNT], writer_ids[WRITERS_COUNT]; for (int i = 0; i < READERS_COUNT; i++) { reader_ids[i] = i + 1; pthread_create(&readers[i], NULL, reader, &reader_ids[i]); } for (int i = 0; i < WRITERS_COUNT; i++) { writer_ids[i] = i + 1; pthread_create(&writers[i], NULL, writer, &writer_ids[i]); } for (int i = 0; i < READERS_COUNT; i++) { pthread_join(readers[i], NULL); } for (int i = 0; i < WRITERS_COUNT; i++) { pthread_join(writers[i], NULL); } pthread_mutex_destroy(&read_mutex); pthread_mutex_destroy(&write_mutex); pthread_cond_destroy(&read_cond); pthread_cond_destroy(&write_cond); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值