怎么使用C++单例模式实现线程池

其他教程   发布日期:2025年03月24日   浏览次数:96

这篇文章主要介绍了怎么使用C++单例模式实现线程池的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用C++单例模式实现线程池文章都会有所收获,下面我们一起来看看吧。

C语言单例模式实现线程池。

该代码中,使用了单例模式来创建线程池对象,保证了整个程序中只有一个线程池对象。

线程池中包含了任务队列、工作线程数组、互斥锁、条件变量等成员,通过这些成员来实现任务的提交和执行。

在主函数中,提交了10个任务,每个任务都是一个简单的打印数字的函数,最后等待所有任务执行完毕后销毁线程池。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #define THREAD_POOL_SIZE 5
  5. // 任务结构体
  6. typedef struct {
  7. void (*task)(void*);
  8. void* arg;
  9. } Task;
  10. // 线程池结构体
  11. typedef struct {
  12. Task* tasks; // 任务队列
  13. int size; // 任务队列大小
  14. int head; // 任务队列头指针
  15. int tail; // 任务队列尾指针
  16. int count; // 任务队列中任务数量
  17. pthread_mutex_t lock; // 互斥锁
  18. pthread_cond_t not_empty; // 非空条件变量
  19. pthread_cond_t not_full; // 非满条件变量
  20. int shutdown; // 线程池是否关闭
  21. pthread_t* threads; // 工作线程数组
  22. int thread_count; // 工作线程数量
  23. } ThreadPool;
  24. // 线程池单例结构体
  25. typedef struct {
  26. ThreadPool* pool; // 线程池指针
  27. } ThreadPoolSingleton;
  28. static ThreadPoolSingleton* instance = NULL; // 线程池单例对象指针
  29. // 工作线程函数
  30. void* worker(void* arg) {
  31. ThreadPool* pool = (ThreadPool*)arg;
  32. while (1) {
  33. pthread_mutex_lock(&pool->lock);
  34. while (pool->count == 0 && !pool->shutdown) {
  35. pthread_cond_wait(&pool->not_empty, &pool->lock);
  36. }
  37. if (pool->count == 0 && pool->shutdown) {
  38. pthread_mutex_unlock(&pool->lock);
  39. pthread_exit(NULL);
  40. }
  41. Task task = pool->tasks[pool->head];
  42. pool->head = (pool->head + 1) % pool->size;
  43. pool->count--;
  44. pthread_cond_signal(&pool->not_full);
  45. pthread_mutex_unlock(&pool->lock);
  46. task.task(task.arg);
  47. }
  48. return NULL;
  49. }
  50. // 创建线程池函数
  51. ThreadPool* create_thread_pool(int thread_count, int queue_size) {
  52. ThreadPool* pool = (ThreadPool*)malloc(sizeof(ThreadPool));
  53. pool->tasks = (Task*)malloc(sizeof(Task) * queue_size);
  54. pool->size = queue_size;
  55. pool->head = 0;
  56. pool->tail = 0;
  57. pool->count = 0;
  58. pthread_mutex_init(&pool->lock, NULL);
  59. pthread_cond_init(&pool->not_empty, NULL);
  60. pthread_cond_init(&pool->not_full, NULL);
  61. pool->shutdown = 0;
  62. pool->threads = (pthread_t*)malloc(sizeof(pthread_t) * thread_count);
  63. pool->thread_count = thread_count;
  64. for (int i = 0; i < thread_count; i++) {
  65. pthread_create(&pool->threads[i], NULL, worker, pool);
  66. }
  67. return pool;
  68. }
  69. // 销毁线程池函数
  70. void destroy_thread_pool(ThreadPool* pool) {
  71. pthread_mutex_lock(&pool->lock);
  72. pool->shutdown = 1;
  73. pthread_mutex_unlock(&pool->lock);
  74. pthread_cond_broadcast(&pool->not_empty);
  75. for (int i = 0; i < pool->thread_count; i++) {
  76. pthread_join(pool->threads[i], NULL);
  77. }
  78. free(pool->threads);
  79. free(pool->tasks);
  80. pthread_mutex_destroy(&pool->lock);
  81. pthread_cond_destroy(&pool->not_empty);
  82. pthread_cond_destroy(&pool->not_full);
  83. free(pool);
  84. }
  85. // 提交任务函数
  86. void submit_task(ThreadPool* pool, void (*task)(void*), void* arg) {
  87. pthread_mutex_lock(&pool->lock);
  88. while (pool->count == pool->size && !pool->shutdown) {
  89. pthread_cond_wait(&pool->not_full, &pool->lock);
  90. }
  91. if (pool->shutdown) {
  92. pthread_mutex_unlock(&pool->lock);
  93. return;
  94. }
  95. pool->tasks[pool->tail].task = task;
  96. pool->tasks[pool->tail].arg = arg;
  97. pool->tail = (pool->tail + 1) % pool->size;
  98. pool->count++;
  99. pthread_cond_signal(&pool->not_empty);
  100. pthread_mutex_unlock(&pool->lock);
  101. }
  102. // 任务函数
  103. void task_func(void* arg) {
  104. int* num = (int*)arg;
  105. printf("task %d is running
  106. ", *num);
  107. free(num);
  108. }
  109. // 任务包装函数
  110. void* task_wrapper(void* arg) {
  111. TaskWrapper* wrapper = (TaskWrapper*)arg;
  112. submit_task(wrapper->pool, wrapper->task, wrapper->arg);
  113. free(wrapper);
  114. return NULL;
  115. }
  116. init_instance() {
  117. instance = (ThreadPoolSingleton*)malloc(sizeof(ThreadPoolSingleton));
  118. instance->pool = create_thread_pool(THREAD_POOL_SIZE, THREAD_POOL_SIZE);
  119. }
  120. // 获取线程池单例对象函数
  121. ThreadPool* get_thread_pool_instance() {
  122. return instance->pool;
  123. }
  124. int main() {
  125. init_instance(); /* 程序一开始,就必须执行。不然,与懒汉式无较大差异 */
  126. ThreadPool* pool = get_thread_pool_instance(); // 获取线程池单例对象
  127. for (int i = 0; i < 10; i++) {
  128. int* num = (int*)malloc(sizeof(int));
  129. *num = i;
  130. TaskWrapper* wrapper = (TaskWrapper*)malloc(sizeof(TaskWrapper));
  131. wrapper->pool = pool
  132. wrapper->task = task_func;
  133. wrapper->arg = num;
  134. pthread_t tid;
  135. pthread_create(&tid, NULL, task_wrapper, wrapper); // 提交任务
  136. }
  137. sleep(1); // 等待所有任务执行完毕
  138. destroy_thread_pool(pool); // 销毁线程池
  139. return 0;
  140. }
  141. /*
  142. 该示例代码中,使用了单例模式来创建线程池对象,保证了整个程序中只有一个线程池对象。
  143. 线程池中包含了任务队列、工作线程数组、互斥锁、条件变量等成员,通过这些成员来实现任务的提交和执行。
  144. 在主函数中,提交了10个任务,每个任务都是一个简单的打印数字的函数,最后等待所有任务执行完毕后销毁线程池。
  145. */

以上就是怎么使用C++单例模式实现线程池的详细内容,更多关于怎么使用C++单例模式实现线程池的资料请关注九品源码其它相关文章!