#include <stdio.h>\n#include <stdlib.h>\n#include <pthread.h>\n#include <windows.h>\ntypedef struct QueueNode {\n int id;\n struct QueueNode* next;\n}QueueNode;\ntypedef struct TaskQueue {\n QueueNode* front;\n QueueNode* rear;\n}TaskQueue;\nint InitQueue(TaskQueue* Qp) {\n Qp->rear = Qp->front = (QueueNode*)malloc(sizeof(QueueNode));\n Qp->front->id = 2018;\n Qp->front->next = NULL;\n return 1;\n}\nint EnQueue(TaskQueue* Qp, int e) {\n QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));\n if (newnode == NULL)\n return 0;\n newnode->id = e;\n newnode->next = NULL;\n Qp->rear->next = newnode;\n Qp->rear = newnode;\n return 1;\n}\nint DeQueue(TaskQueue* Qp, int* ep, int threadID) {\n QueueNode* deletenode;\n if (Qp->rear == Qp->front)\n return 0;\n deletenode = Qp->front->next;\n if (deletenode == NULL) {\n return 0;\n }\n ep = deletenode->id;\n Qp->front->next = deletenode->next;\n free(deletenode);\n return 1;\n}\nint GetNextTask();\nint thread_count, finished = 0;\npthread_mutex_t mutex, mutex2;\npthread_cond_t cond;\nvoid task(void* rank);\nTaskQueue Q;\nint main()\n{\n int n;\n InitQueue(&Q);\n pthread_t* thread_handles;\n thread_count = 8;\n thread_handles = malloc(thread_count * sizeof(pthread_t));\n pthread_mutex_init(&mutex, NULL);\n pthread_mutex_init(&mutex2, NULL);\n pthread_cond_init(&cond, NULL);\n printf("Task Number:");\n scanf_s("%d", &n);\n for (int i = 0; i < thread_count; i++)\n pthread_create(&thread_handles[i], NULL, task, (void*)i);\n for (int i = 0; i < n; i++) {\n pthread_mutex_lock(&mutex2);\n EnQueue(&Q, i);\n Sleep(1);\n pthread_cond_signal(&cond);\n pthread_mutex_unlock(&mutex2);\n }\n finished = 1;\n pthread_cond_broadcast(&cond);\n for (int i = 0; i < thread_count; i++)\n pthread_join(thread_handles[i], NULL);\n pthread_mutex_destroy(&mutex);\n pthread_cond_destroy(&cond);\n free(thread_handles);\n return 0;\n}\nvoid* task(void* rank) {\n int my_rank = (long)rank;\n int my_task;\n QueueNode** p = &(Q.front->next);\n while (1) {\n pthread_mutex_lock(&mutex2);\n if (finished) {\n if (*p == NULL) {\n pthread_mutex_unlock(&mutex2);\n break;\n }\n DeQueue(&Q, &my_task, my_rank);\n pthread_mutex_unlock(&mutex2);\n printf("From thread %ld: Task no.%-3d result->%5d\n", my_rank, my_task, my_task * 10);\n\n }\n else {\n while(pthread_cond_wait(&cond, &mutex2)!=0);\n //pthread_mutex_lock(&mutex2);\n DeQueue(&Q, &my_task, my_rank);\n pthread_mutex_unlock(&mutex2);\n Sleep(2);\n printf("From thread %ld: Task no.%-3d result->%5d\n", my_rank, my_task, my_task * 10);\n }\n }\n}\n\n的设计思想\n内容:这段代码实现了一个多线程并发执行任务的程序。主要的设计思想是使用一个任务队列来存储需要执行的任务,每个线程从队列中获取任务并执行,直到队列为空。主线程负责将任务添加到队列中,并在所有任务执行完毕后结束程序。\n\n具体的设计包括以下几个部分:\n\n1. 定义了一个结构体QueueNode来表示任务队列中的节点,包含任务的id和指向下一个节点的指针。\n\n2. 定义了一个结构体TaskQueue来表示任务队列,包含队列的头节点和尾节点。\n\n3. 实现了初始化队列的函数InitQueue,将队列初始化为空队列。\n\n4. 实现了入队函数EnQueue,将一个新的任务添加到队列的尾部。\n\n5. 实现了出队函数DeQueue,从队列的头部取出一个任务并返回任务的id。\n\n6. 实现了获取下一个任务的函数GetNextTask,用于获取队列中的下一个任务。\n\n7. 定义了全局变量thread_count和finished,分别表示线程的数量和所有任务是否执行完毕。\n\n8. 使用互斥锁mutex和mutex2来保护对任务队列的访问,使用条件变量cond来实现线程的同步。\n\n9. 实现了任务函数task,每个线程执行该函数来获取任务并执行。在任务队列为空时,线程会等待条件变量的信号,直到有新的任务添加到队列中或者所有任务执行完毕。\n\n10. 主线程负责将任务添加到队列中,并在所有任务执行完毕后结束程序。

多线程并发执行任务的C语言程序:使用任务队列和线程同步

原文地址: https://www.cveoy.top/t/topic/pPlJ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录