编写一个Pthreads程序实现一个任务队列。主线程启动用户指定数量的线程这些线程进入条件等待状态。主线程生成一些任务一定计算量每生成一个新的任务就用条件变量唤醒一个线程当这个唤醒线程执行完任务时回到条件等待状态。当主线程生成完所有任务设置全局变量表示再没有要生成的任务了并用一个广播唤醒所有线程。为了清晰起见建议任务采用链表操作。
下面是一个使用Pthreads库实现任务队列的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct task {
int id;
struct task* next;
} task_t;
task_t* head = NULL;
task_t* tail = NULL;
int num_tasks = 0;
int num_threads = 0;
int done = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void enqueue_task(int id) {
task_t* new_task = (task_t*)malloc(sizeof(task_t));
new_task->id = id;
new_task->next = NULL;
pthread_mutex_lock(&mutex);
if (head == NULL) {
head = new_task;
tail = new_task;
} else {
tail->next = new_task;
tail = new_task;
}
num_tasks++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
task_t* dequeue_task() {
pthread_mutex_lock(&mutex);
while (head == NULL && !done) {
pthread_cond_wait(&cond, &mutex);
}
if (head == NULL) {
pthread_mutex_unlock(&mutex);
return NULL;
}
task_t* task = head;
head = head->next;
num_tasks--;
pthread_mutex_unlock(&mutex);
return task;
}
void* worker(void* arg) {
int thread_id = *(int*)arg;
while (1) {
task_t* task = dequeue_task();
if (task == NULL) {
break;
}
printf("Thread %d executing task %d\n", thread_id, task->id);
// do some work with the task
free(task);
}
printf("Thread %d exiting\n", thread_id);
return NULL;
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage: %s <num_threads> <num_tasks>\n", argv[0]);
return 1;
}
num_threads = atoi(argv[1]);
int num_tasks = atoi(argv[2]);
pthread_t* threads = (pthread_t*)malloc(num_threads * sizeof(pthread_t));
int* thread_ids = (int*)malloc(num_threads * sizeof(int));
for (int i = 0; i < num_threads; i++) {
thread_ids[i] = i;
pthread_create(&threads[i], NULL, worker, &thread_ids[i]);
}
for (int i = 0; i < num_tasks; i++) {
enqueue_task(i);
}
done = 1;
pthread_cond_broadcast(&cond);
for (int i = 0; i < num_threads; i++) {
pthread_join(threads[i], NULL);
}
free(threads);
free(thread_ids);
return 0;
}
在这个示例程序中,我们使用一个全局的任务队列,以链表的形式保存任务。主线程通过调用enqueue_task()函数将任务添加到队列中。每当有新任务添加到队列时,主线程会通过条件变量cond唤醒一个等待中的线程。线程通过调用dequeue_task()函数来从队列中取出任务并执行。如果队列为空且主线程已经生成完所有任务,则线程会进入条件等待状态。当主线程生成完所有任务后,它会设置done变量为1,并通过调用pthread_cond_broadcast()函数广播唤醒所有等待中的线程。每个线程在执行完一个任务后会释放任务所占用的内存。
这个示例程序使用命令行参数来指定线程数量和任务数量。可以通过以下命令编译和运行程序:
gcc -o task_queue task_queue.c -pthread
./task_queue <num_threads> <num_tasks>
注意,这个示例程序没有对线程数量和任务数量进行错误检查,建议在实际使用时添加错误处理逻辑
原文地址: https://www.cveoy.top/t/topic/h2FD 著作权归作者所有。请勿转载和采集!