编写OpenMP程序一些线程是生产者一些线程是消费者。在文件集合中每个生产者针对一个文件从文件中读取文本将读出的文本行插入到一个共享的队列中。消费者从队列中取出文本行并对文本行进行分词strtok函数。符号是被空白符分开的单词当消费者发现一个单词后将单词输出。体会线程安全性
以下是使用OpenMP编写的生产者-消费者程序的示例代码。在该示例中,每个生产者线程负责从文件中读取文本行,并将其插入到共享队列中。消费者线程从队列中取出文本行,并对其进行分词操作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#define MAX_LINE_LENGTH 100
// 定义共享队列
typedef struct {
char** lines;
int front;
int rear;
int size;
} Queue;
// 初始化队列
void initQueue(Queue* q, int size) {
q->lines = (char**)malloc(size * sizeof(char*));
q->front = 0;
q->rear = -1;
q->size = 0;
}
// 插入元素到队列
void enqueue(Queue* q, char* line) {
q->rear = (q->rear + 1) % q->size;
q->lines[q->rear] = line;
q->size++;
}
// 从队列中取出元素
char* dequeue(Queue* q) {
char* line = q->lines[q->front];
q->front = (q->front + 1) % q->size;
q->size--;
return line;
}
// 生产者线程函数
void producer(int thread_id, Queue* q, const char* filename) {
FILE* file = fopen(filename, "r");
if (file == NULL) {
printf("Unable to open file: %s\n", filename);
return;
}
char* line = (char*)malloc(MAX_LINE_LENGTH * sizeof(char));
while (fgets(line, MAX_LINE_LENGTH, file) != NULL) {
// 在读取的文本行后添加到队列中
#pragma omp critical
enqueue(q, strdup(line));
}
fclose(file);
free(line);
}
// 消费者线程函数
void consumer(int thread_id, Queue* q) {
while (1) {
char* line;
// 从队列中取出文本行
#pragma omp critical
{
if (q->size == 0) {
// 队列为空,结束消费者线程
return;
}
line = dequeue(q);
}
// 对文本行进行分词并输出单词
char* token = strtok(line, " \t\n");
while (token != NULL) {
printf("Consumer %d: %s\n", thread_id, token);
token = strtok(NULL, " \t\n");
}
free(line);
}
}
int main() {
const int num_producers = 2;
const int num_consumers = 4;
const char* filenames[] = {"file1.txt", "file2.txt"};
Queue q;
initQueue(&q, num_producers * 10); // 假设每个生产者线程平均读取10行文本
#pragma omp parallel num_threads(num_producers + num_consumers)
{
int thread_id = omp_get_thread_num();
if (thread_id < num_producers) {
// 生产者线程
const char* filename = filenames[thread_id];
producer(thread_id, &q, filename);
} else {
// 消费者线程
consumer(thread_id - num_producers, &q);
}
}
return 0;
}
在上述代码中,我们使用了OpenMP中的#pragma omp critical指令来确保对共享队列的访问是线程安全的。这样,每个生产者线程都可以安全地将文本行插入队列中,而消费者线程可以安全地从队列中取出文本行并进行分词操作。
请注意,上述代码中的队列实现并不是线程安全的,为了确保线程安全性,我们使用了#pragma omp critical指令对队列的访问进行了保护。在实际的应用中,你可能需要使用更高效的线程安全数据结构(如线程安全队列)来避免不必要的锁竞争
原文地址: http://www.cveoy.top/t/topic/ib2T 著作权归作者所有。请勿转载和采集!