请用c语言编写linux环境下运行的一个程序,其功能为实现生产者消费者功能,要去生产者任务从文件中读取数据,并将它存放到缓冲区,而消费者任务从缓冲区中取走此数据,并打印输出。
时间: 2024-02-22 22:55:06 浏览: 62
Linux环境下C语言实现生产者消费者问题的代码
以下是一个简单的生产者消费者模型的C语言程序,其中生产者任务从文件中读取数据并将其存储在缓冲区中,而消费者任务从缓冲区中获取数据并将其打印输出。该程序使用了线程、互斥锁和条件变量来实现生产者消费者模型。
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 10
char buffer[BUFFER_SIZE]; // 缓冲区
int buffer_index = 0; // 缓冲区索引
pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER; // 缓冲区互斥锁
pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER; // 缓冲区条件变量
void *producer(void *arg) {
FILE *file = fopen((char *)arg, "r");
char data;
while ((data = fgetc(file)) != EOF) {
pthread_mutex_lock(&buffer_mutex); // 加锁
while (buffer_index == BUFFER_SIZE) { // 缓冲区已满,等待消费者消费
pthread_cond_wait(&buffer_cond, &buffer_mutex);
}
buffer[buffer_index] = data; // 生产者存入数据到缓冲区
buffer_index++;
pthread_cond_signal(&buffer_cond); // 唤醒消费者
pthread_mutex_unlock(&buffer_mutex); // 解锁
}
fclose(file);
return NULL;
}
void *consumer(void *arg) {
while (1) {
pthread_mutex_lock(&buffer_mutex); // 加锁
while (buffer_index == 0) { // 缓冲区为空,等待生产者生产
pthread_cond_wait(&buffer_cond, &buffer_mutex);
}
char data = buffer[buffer_index - 1]; // 消费者从缓冲区获取数据
buffer_index--;
pthread_cond_signal(&buffer_cond); // 唤醒生产者
pthread_mutex_unlock(&buffer_mutex); // 解锁
printf("%c", data); // 打印输出
fflush(stdout); // 刷新输出缓冲区
}
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return -1;
}
pthread_t producer_thread, consumer_thread;
pthread_create(&producer_thread, NULL, producer, argv[1]);
pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
return 0;
}
```
在上面的代码中,我们首先定义了一个长度为10的缓冲区和一个缓冲区索引变量。然后,我们创建了一个互斥锁和一个条件变量,用来实现线程同步。
在生产者线程函数中,我们打开了一个文件,然后逐个字符读取文件中的数据。每次读取一个字符后,我们先获取缓冲区的互斥锁,然后判断缓冲区是否已满。如果缓冲区已满,则调用pthread_cond_wait()函数等待消费者消费。如果缓冲区未满,则将数据存储到缓冲区中,然后唤醒消费者线程,并释放缓冲区的互斥锁。
在消费者线程函数中,我们首先获取缓冲区的互斥锁,然后判断缓冲区是否为空。如果缓冲区为空,则调用pthread_cond_wait()函数等待生产者生产。如果缓冲区不为空,则从缓冲区中获取数据,然后唤醒生产者线程,并释放缓冲区的互斥锁。最后,我们将获取到的数据打印输出。
在主函数中,我们首先判断命令行参数是否正确,然后创建生产者线程和消费者线程,并等待生产者线程和消费者线程执行完毕后,程序结束。
阅读全文