编写C语言的OpenMP程序一些线程是生产者一些线程是消费者。在文件集合中每个生产者针对一个文件从文件中读取文本将读出的文本行插入到一个共享的队列中。消费者从队列中取出文本行并对文本行进行分词strtok函数。符号是被空白符分开的单词当消费者发现一个单词后将单词输出。体会线程安全性
以下是一个使用OpenMP编写的生产者-消费者程序的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#define MAX_LINE_LENGTH 100
struct Queue {
char** lines;
int front;
int rear;
int size;
};
struct Queue* createQueue(int size) {
struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
queue->lines = (char**) malloc(size * sizeof(char*));
queue->front = 0;
queue->rear = -1;
queue->size = 0;
return queue;
}
void enqueue(struct Queue* queue, char* line) {
queue->rear = (queue->rear + 1) % queue->size;
queue->lines[queue->rear] = line;
queue->size++;
}
char* dequeue(struct Queue* queue) {
char* line = queue->lines[queue->front];
queue->front = (queue->front + 1) % queue->size;
queue->size--;
return line;
}
void tokenizeLine(char* line) {
char* token = strtok(line, " ");
while (token != NULL) {
printf("Word: %s\n", token);
token = strtok(NULL, " ");
}
}
int main() {
int num_producers = 4;
int num_consumers = 2;
int queue_size = 10;
struct Queue* queue = createQueue(queue_size);
#pragma omp parallel num_threads(num_producers + num_consumers)
{
int thread_id = omp_get_thread_num();
if (thread_id < num_producers) {
char filename[10];
sprintf(filename, "file%d.txt", thread_id + 1);
FILE* file = fopen(filename, "r");
if (file == NULL) {
printf("Failed to open file: %s\n", filename);
exit(1);
}
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), file) != NULL) {
#pragma omp critical
{
enqueue(queue, strdup(line));
}
}
fclose(file);
} else {
while (1) {
char* line;
#pragma omp critical
{
if (queue->size > 0) {
line = dequeue(queue);
} else {
line = NULL;
}
}
if (line == NULL) {
break;
}
tokenizeLine(line);
free(line);
}
}
}
return 0;
}
在此示例中,我们使用struct Queue表示共享的队列。createQueue函数用于创建队列,enqueue函数用于将行插入队列,dequeue函数用于从队列中取出行。tokenizeLine函数用于对文本行进行分词并输出单词。
在main函数中,我们使用OpenMP的#pragma omp parallel指令创建了多个线程。前num_producers个线程是生产者,每个生产者根据文件名从文件中读取文本行,并将其插入到共享队列中。后num_consumers个线程是消费者,它们从队列中取出行,并对行进行分词并输出。
为了保证队列的线程安全性,我们使用#pragma omp critical指令将对队列的访问操作进行了保护。这样一来,每次只有一个线程可以执行队列的插入和删除操作,从而避免了竞争条件。
此示例中假设有4个生产者线程和2个消费者线程。您可以根据实际需求调整这些参数。另外,请确保在运行程序之前创建了名为file1.txt、file2.txt、file3.txt和file4.txt的文本文件,并在文件中填充一些文本行以供读取
原文地址: http://www.cveoy.top/t/topic/ib26 著作权归作者所有。请勿转载和采集!