生产者消费者c语言线程
时间: 2023-11-07 07:43:38 浏览: 76
在 C 语言中,通过线程能够实现生产者-消费者模式。生产者负责向缓冲区中生产数据,消费者则负责从缓冲区中取出数据进行消费。为了避免生产者与消费者之间的竞争,需要利用互斥量来保护缓冲区的访问。同时,为了确保当缓冲区为空时消费者不会继续消费数据,需要用条件变量来实现消费者的等待和唤醒。具体的实现方法可以参考 Pthreads 线程库中的函数,如 pthread_mutex_lock()、pthread_mutex_unlock()、pthread_cond_wait()、pthread_cond_signal() 等。
相关问题
生产者消费者多线程c语言
生产者消费者问题是一个经典的多线程同步问题,可以使用信号量来解决。以下是一个简单的 C 语言实现:
```c
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define PRODUCER_NUM 2
#define CONSUMER_NUM 2
sem_t empty, full;
pthread_mutex_t mutex;
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
void *producer(void *arg) {
int id = *(int *)arg;
while (1) {
int item = rand() % 1000;
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
printf("Producer %d produced item %d\n", id, item);
pthread_mutex_unlock(&mutex);
sem_post(&full);
sleep(rand() % 3);
}
}
void *consumer(void *arg) {
int id = *(int *)arg;
while (1) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
int item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
printf("Consumer %d consumed item %d\n", id, item);
pthread_mutex_unlock(&mutex);
sem_post(&empty);
sleep(rand() % 3);
}
}
int main() {
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
pthread_t tid[PRODUCER_NUM + CONSUMER_NUM];
int id[PRODUCER_NUM + CONSUMER_NUM];
for (int i = 0; i < PRODUCER_NUM; i++) {
id[i] = i;
pthread_create(&tid[i], NULL, producer, &id[i]);
}
for (int i = 0; i < CONSUMER_NUM; i++) {
id[PRODUCER_NUM + i] = i;
pthread_create(&tid[PRODUCER_NUM + i], NULL, consumer, &id[PRODUCER_NUM + i]);
}
for (int i = 0; i < PRODUCER_NUM + CONSUMER_NUM; i++) {
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&mutex);
sem_destroy(&full);
sem_destroy(&empty);
return 0;
}
```
在程序中,我们使用了两个信号量 `empty` 和 `full` 分别表示空闲缓冲区的数量和已占用缓冲区的数量。对于生产者线程,每当一个新的 item 被生产出来,需要先等待 `empty` 信号量,表示有空闲的缓冲区可以使用。然后获取互斥锁,将 item 放入缓冲区中,更新 `in` 指针,表示下一个可用的缓冲区。最后释放互斥锁,增加 `full` 信号量,表示已占用的缓冲区数量加 1。
对于消费者线程,每当需要消费一个 item,需要先等待 `full` 信号量,表示有已占用的缓冲区可以使用。然后获取互斥锁,从缓冲区中取出 item,更新 `out` 指针,表示下一个可用的缓冲区。最后释放互斥锁,增加 `empty` 信号量,表示空闲的缓冲区数量加 1。
最后,我们创建多个生产者线程和消费者线程,并等待所有线程结束。注意需要在程序结束时销毁互斥锁和信号量。
生产者消费者问题c语言
生产者消费者问题是一个经典的并发问题,涉及两个或多个线程之间的协作和同步。生产者负责生产数据并将其放入缓冲区,消费者则从缓冲区中获取数据并进行处理。生产者和消费者必须在缓冲区上进行同步,以避免竞争条件和死锁。
下面是一个使用C语言实现的生产者消费者问题的示例代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t full = PTHREAD_COND_INITIALIZER;
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
void *producer(void *arg)
{
int item;
while (1) {
item = rand() % 100; // 生成一个随机数
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
pthread_cond_wait(&empty, &mutex);
}
buffer[count++] = item;
printf("Producer produced item %d\n", item);
pthread_cond_signal(&full);
pthread_mutex_unlock(&mutex);
sleep(1);
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
int item;
while (1) {
pthread_mutex_lock(&mutex);
while (count == 0) {
pthread_cond_wait(&full, &mutex);
}
item = buffer[--count];
printf("Consumer consumed item %d\n", item);
pthread_cond_signal(&empty);
pthread_mutex_unlock(&mutex);
sleep(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid1, tid2;
srand(time(NULL));
pthread_create(&tid1, NULL, producer, NULL);
pthread_create(&tid2, NULL, consumer, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
```
在这个示例中,我们使用了一个整型数组作为缓冲区,其大小为10。在主函数中,我们创建了两个线程,一个用于生产数据,另一个用于消费数据。生产者和消费者共同使用了一个互斥锁(mutex),以保证缓冲区的访问是互斥的。生产者使用了一个条件变量(full)来等待缓冲区不满,消费者使用了另一个条件变量(empty)来等待缓冲区不空。当生产者向缓冲区中放入一个数据时,它会发送一个full信号,通知消费者缓冲区中有数据可用。当消费者从缓冲区中取出一个数据时,它会发送一个empty信号,通知生产者缓冲区中有空间可用。
在生产者和消费者的代码中,我们使用了while循环来检查条件是否满足。如果条件不满足,线程会调用pthread_cond_wait函数来等待条件变量。当条件满足时,线程会被唤醒,并继续执行。注意,在等待条件变量之前,线程必须先获得互斥锁,以避免竞争条件。在发送信号之前,线程必须先释放互斥锁,以允许其他线程访问共享资源。
阅读全文