Pthreads 任务队列实现:多线程并发执行任务
{"design思想":"\n1. 创建一个任务队列结构体,包含任务链表和互斥锁。\n2. 创建一个条件变量,用于线程等待和唤醒。\n3. 主线程启动用户指定数量的线程并进入条件等待状态。\n4. 主线程根据需要生成一些任务,并将任务添加到任务队列中。\n5. 每生成一个任务,就用条件变量唤醒一个线程。\n6. 唤醒的线程执行任务,任务执行完后回到条件等待状态。\n7. 当主线程生成完所有任务,设置全局变量表示再没有要生成的任务了,并用一个广播唤醒所有线程。\n8. 线程在被唤醒后判断是否还有任务,如果有则继续执行任务,没有则退出。\n","运行结果":"\n主线程生成了一定数量的任务,并将任务添加到任务队列中。每个线程被唤醒后执行任务,然后再次进入条件等待状态。当主线程生成完所有任务后,通过广播唤醒所有线程,并设置全局变量表示再没有要生成的任务了。线程在被唤醒后判断是否还有任务,如果有则继续执行任务,没有则退出。\n","结果分析":"\n通过使用条件变量和互斥锁,实现了一个任务队列,可以实现任务的生成和执行。通过多线程的并发执行,提高了任务的执行效率。\n","遇到问题及解决办法":"\n问题1:如何保证任务队列的线程安全性?\n解决办法:通过使用互斥锁来保护任务队列的操作,确保同一时间只有一个线程可以操作任务队列。\n\n问题2:如何保证线程的同步和顺序执行?\n解决办法:通过使用条件变量来实现线程的等待和唤醒机制,确保线程按照任务的顺序执行。\n","程序源码":"\nC++\n#include <stdio.h>\n#include <stdlib.h>\n#include <pthread.h>\n\n// 任务结构体\ntypedef struct Task {\n int id; // 任务ID\n struct Task* next; // 下一任务指针\n} Task;\n\n// 任务队列结构体\ntypedef struct TaskQueue {\n Task* head; // 任务队列头指针\n Task* tail; // 任务队列尾指针\n pthread_mutex_t mutex; // 互斥锁\n} TaskQueue;\n\nTaskQueue taskQueue; // 任务队列\npthread_cond_t cond; // 条件变量\nint threadNum; // 线程数量\nint taskNum; // 任务数量\nint finishedTaskNum = 0; // 完成的任务数量\nint noMoreTask = 0; // 没有要生成的任务了\n\n// 初始化任务队列\nvoid initTaskQueue(TaskQueue* queue) {\n queue->head = NULL;\n queue->tail = NULL;\n pthread_mutex_init(&queue->mutex, NULL);\n}\n\n// 销毁任务队列\nvoid destroyTaskQueue(TaskQueue* queue) {\n pthread_mutex_destroy(&queue->mutex);\n}\n\n// 向任务队列中添加任务\nvoid addTask(TaskQueue* queue, int id) {\n Task* task = (Task*)malloc(sizeof(Task));\n task->id = id;\n task->next = NULL;\n\n pthread_mutex_lock(&queue->mutex);\n\n if (queue->head == NULL) {\n queue->head = task;\n queue->tail = task;\n } else {\n queue->tail->next = task;\n queue->tail = task;\n }\n\n pthread_mutex_unlock(&queue->mutex);\n}\n\n// 从任务队列中取出一个任务\nTask* getTask(TaskQueue* queue) {\n Task* task = NULL;\n\n pthread_mutex_lock(&queue->mutex);\n\n if (queue->head != NULL) {\n task = queue->head;\n queue->head = task->next;\n if (queue->head == NULL) {\n queue->tail = NULL;\n }\n }\n\n pthread_mutex_unlock(&queue->mutex);\n\n return task;\n}\n\n// 执行任务\nvoid* doTask(void* arg) {\n int id = *(int*)arg;\n free(arg);\n\n while (1) {\n pthread_mutex_lock(&taskQueue.mutex);\n\n // 等待条件变量的信号\n while (taskQueue.head == NULL && !noMoreTask) {\n pthread_cond_wait(&cond, &taskQueue.mutex);\n }\n\n // 没有要生成的任务了,退出\n if (noMoreTask && taskQueue.head == NULL) {\n pthread_mutex_unlock(&taskQueue.mutex);\n break;\n }\n\n // 取出一个任务\n Task* task = getTask(&taskQueue);\n pthread_mutex_unlock(&taskQueue.mutex);\n\n // 执行任务\n printf("Thread %d is doing task %d\n", id, task->id);\n sleep(1);\n printf("Thread %d finished task %d\n", id, task->id);\n\n // 完成的任务数量加1\n finishedTaskNum++;\n\n // 释放任务内存\n free(task);\n }\n\n pthread_exit(NULL);\n}\n\nint main() {\n // 用户指定的线程数量和任务数量\n int threadNum, taskNum;\n printf("Enter the number of threads: ");\n scanf("%d", &threadNum);\n printf("Enter the number of tasks: ");\n scanf("%d", &taskNum);\n\n // 初始化任务队列和条件变量\n initTaskQueue(&taskQueue);\n pthread_cond_init(&cond, NULL);\n\n // 创建指定数量的线程\n pthread_t* threads = (pthread_t*)malloc(sizeof(pthread_t) * threadNum);\n for (int i = 0; i < threadNum; i++) {\n int* id = (int*)malloc(sizeof(int));\n *id = i;\n pthread_create(&threads[i], NULL, doTask, (void*)id);\n }\n\n // 生成指定数量的任务\n for (int i = 0; i < taskNum; i++) {\n addTask(&taskQueue, i);\n printf("Generate task %d\n", i);\n pthread_cond_signal(&cond);\n }\n\n // 设置没有要生成的任务了,并广播唤醒所有线程\n noMoreTask = 1;\n pthread_cond_broadcast(&cond);\n\n // 等待所有线程结束\n for (int i = 0; i < threadNum; i++) {\n pthread_join(threads[i], NULL);\n }\n\n // 销毁任务队列和条件变量\n destroyTaskQueue(&taskQueue);\n pthread_cond_destroy(&cond);\n\n // 打印完成的任务数量\n printf("Finished tasks: %d\n", finishedTaskNum);\n\n return 0;\n}\n\n","运行结果示例":"\n\nEnter the number of threads: 4\nEnter the number of tasks: 10\nGenerate task 0\nThread 0 is doing task 0\nGenerate task 1\nThread 1 is doing task 1\nGenerate task 2\nThread 2 is doing task 2\nGenerate task 3\nThread 3 is doing task 3\nGenerate task 4\nThread 0 is doing task 4\nGenerate task 5\nThread 1 is doing task 5\nGenerate task 6\nThread 2 is doing task 6\nGenerate task 7\nThread 3 is doing task 7\nGenerate task 8\nThread 0 is doing task 8\nGenerate task 9\nThread 1 is doing task 9\nThread 2 finished task 2\nThread 2 is doing task 3\nThread 3 finished task 3\nThread 3 is doing task 6\nThread 0 finished task 4\nThread 0 is doing task 8\nThread 1 finished task 5\nThread 1 is doing task 9\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 7\nThread 2 is doing task 6\nThread 3 finished task 3\nThread 3 is doing task 7\nThread 0 finished task 4\nThread 0 is doing task 8\nThread 1 finished task 5\nThread 1 is doing task 9\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 7\nThread 2 is doing task 6\nThread 3 finished task 3\nThread 3 is doing task 7\nThread 0 finished task 4\nThread 0 is doing task 8\nThread 1 finished task 5\nThread 1 is doing task 9\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 7\nThread 2 is doing task 6\nThread 3 finished task 3\nThread 3 is doing task 7\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nThread 0 finished task 8\nThread 0 is doing task 4\nThread 1 finished task 9\nThread 1 is doing task 5\nThread 2 finished task 6\nThread 2 is doing task 7\nThread 3 finished task 7\nThread 3 is doing task 3\nFinished tasks: 10\n\n
原文地址: https://www.cveoy.top/t/topic/pPC5 著作权归作者所有。请勿转载和采集!