C++单例模式实现线程池的示例代码

 更新时间:2023年04月20日 16:38:17   作者:Michael_Good  
这篇文章主要为大家详细介绍了如何利用C++单例模式简单实现一个线程池,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下

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

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define THREAD_POOL_SIZE 5

// 任务结构体
typedef struct {
    void (*task)(void*);
    void* arg;
} Task;

// 线程池结构体
typedef struct {
    Task* tasks; // 任务队列
    int size; // 任务队列大小
    int head; // 任务队列头指针
    int tail; // 任务队列尾指针
    int count; // 任务队列中任务数量
    pthread_mutex_t lock; // 互斥锁
    pthread_cond_t not_empty; // 非空条件变量
    pthread_cond_t not_full; // 非满条件变量
    int shutdown; // 线程池是否关闭
    pthread_t* threads; // 工作线程数组
    int thread_count; // 工作线程数量
} ThreadPool;

// 线程池单例结构体
typedef struct {
    ThreadPool* pool; // 线程池指针
} ThreadPoolSingleton;

static ThreadPoolSingleton* instance = NULL; // 线程池单例对象指针

// 工作线程函数
void* worker(void* arg) {
    ThreadPool* pool = (ThreadPool*)arg;
    while (1) {
        pthread_mutex_lock(&pool->lock);
        while (pool->count == 0 && !pool->shutdown) {
            pthread_cond_wait(&pool->not_empty, &pool->lock);
        }
        if (pool->count == 0 && pool->shutdown) {
            pthread_mutex_unlock(&pool->lock);
            pthread_exit(NULL);
        }
        Task task = pool->tasks[pool->head];
        pool->head = (pool->head + 1) % pool->size;
        pool->count--;
        pthread_cond_signal(&pool->not_full);
        pthread_mutex_unlock(&pool->lock);
        task.task(task.arg);
    }
    return NULL;
}

// 创建线程池函数
ThreadPool* create_thread_pool(int thread_count, int queue_size) {
    ThreadPool* pool = (ThreadPool*)malloc(sizeof(ThreadPool));
    pool->tasks = (Task*)malloc(sizeof(Task) * queue_size);
    pool->size = queue_size;
    pool->head = 0;
    pool->tail = 0;
    pool->count = 0;
    pthread_mutex_init(&pool->lock, NULL);
    pthread_cond_init(&pool->not_empty, NULL);
    pthread_cond_init(&pool->not_full, NULL);
    pool->shutdown = 0;
    pool->threads = (pthread_t*)malloc(sizeof(pthread_t) * thread_count);
    pool->thread_count = thread_count;
    for (int i = 0; i < thread_count; i++) {
        pthread_create(&pool->threads[i], NULL, worker, pool);
    }
    return pool;
}

// 销毁线程池函数
void destroy_thread_pool(ThreadPool* pool) {
    pthread_mutex_lock(&pool->lock);
    pool->shutdown = 1;
    pthread_mutex_unlock(&pool->lock);
    pthread_cond_broadcast(&pool->not_empty);
    for (int i = 0; i < pool->thread_count; i++) {
        pthread_join(pool->threads[i], NULL);
    }
    free(pool->threads);
    free(pool->tasks);
    pthread_mutex_destroy(&pool->lock);
    pthread_cond_destroy(&pool->not_empty);
    pthread_cond_destroy(&pool->not_full);
    free(pool);
}

// 提交任务函数
void submit_task(ThreadPool* pool, void (*task)(void*), void* arg) {
    pthread_mutex_lock(&pool->lock);
    while (pool->count == pool->size && !pool->shutdown) {
        pthread_cond_wait(&pool->not_full, &pool->lock);
    }
    if (pool->shutdown) {
        pthread_mutex_unlock(&pool->lock);
        return;
    }
    pool->tasks[pool->tail].task = task;
    pool->tasks[pool->tail].arg = arg;
    pool->tail = (pool->tail + 1) % pool->size;
    pool->count++;
    pthread_cond_signal(&pool->not_empty);
    pthread_mutex_unlock(&pool->lock);
}

// 任务函数
void task_func(void* arg) {
    int* num = (int*)arg;
    printf("task %d is running\n", *num);
    free(num);
}

// 任务包装函数
void* task_wrapper(void* arg) {
    TaskWrapper* wrapper = (TaskWrapper*)arg;
    submit_task(wrapper->pool, wrapper->task, wrapper->arg);
    free(wrapper);
    return NULL;
}

init_instance() {
	instance = (ThreadPoolSingleton*)malloc(sizeof(ThreadPoolSingleton));
	instance->pool = create_thread_pool(THREAD_POOL_SIZE, THREAD_POOL_SIZE);
}
// 获取线程池单例对象函数
ThreadPool* get_thread_pool_instance() {
    return instance->pool;
}

int main() {
	init_instance();	/* 程序一开始,就必须执行。不然,与懒汉式无较大差异 */
    ThreadPool* pool = get_thread_pool_instance(); // 获取线程池单例对象
    for (int i = 0; i < 10; i++) {
        int* num = (int*)malloc(sizeof(int));
        *num = i;
        TaskWrapper* wrapper = (TaskWrapper*)malloc(sizeof(TaskWrapper));
        wrapper->pool = pool
		wrapper->task = task_func;
		wrapper->arg = num;
		pthread_t tid;
		pthread_create(&tid, NULL, task_wrapper, wrapper); // 提交任务
	}
	sleep(1); // 等待所有任务执行完毕
	destroy_thread_pool(pool); // 销毁线程池
	return 0;
}

/*
该示例代码中,使用了单例模式来创建线程池对象,保证了整个程序中只有一个线程池对象。
线程池中包含了任务队列、工作线程数组、互斥锁、条件变量等成员,通过这些成员来实现任务的提交和执行。
在主函数中,提交了10个任务,每个任务都是一个简单的打印数字的函数,最后等待所有任务执行完毕后销毁线程池。
*/

到此这篇关于C++单例模式实现线程池的示例代码的文章就介绍到这了,更多相关C++单例模式实现线程池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解C语言中free()函数与getpagesize()函数的使用

    详解C语言中free()函数与getpagesize()函数的使用

    这篇文章主要介绍了详解C语言中free()函数与getpagesize()函数的使用,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-08-08
  • C++实现LeetCode(143.链表重排序)

    C++实现LeetCode(143.链表重排序)

    这篇文章主要介绍了C++实现LeetCode(143.链表重排序),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Qt编写地图之实现跨平台功能

    Qt编写地图之实现跨平台功能

    这篇文章主要介绍了如何利用Qt编写地图应用时实现跨平台功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-02-02
  • C++类重载函数的function和bind使用示例

    C++类重载函数的function和bind使用示例

    这篇文章主要介绍了C++类重载函数的function和bind使用示例,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下
    2021-01-01
  • Qt定时器类QTimer使用详解与注意事项

    Qt定时器类QTimer使用详解与注意事项

    Qt提供了两种定时器,一种是QObject类的定时器,另一种是QTimer类的定时器,这篇文章主要给大家介绍了关于Qt定时器类QTimer使用与注意事项的相关资料,需要的朋友可以参考下
    2023-10-10
  • 一文带你了解C++中queue的使用

    一文带你了解C++中queue的使用

    C++中的queue是一种容器,用于在FIFO(先进先出)原则下存储和管理元素。本篇文章将深入探讨C++中的queue,包括它的定义、使用、原理和示例,感兴趣的可以了解一下
    2023-04-04
  • 带你粗略了解c++的最大乘积

    带你粗略了解c++的最大乘积

    这篇文章主要为大家详细介绍了C++的最大乘积,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能给你带来帮助
    2021-08-08
  • 使用C语言构建基本的二叉树数据结构

    使用C语言构建基本的二叉树数据结构

    这篇文章主要介绍了使用C语言使用C语言构建基本的二叉树数据结构,包括根据前序序列和中序序列构建二叉树的方法,需要的朋友可以参考下
    2015-08-08
  • C++数据结构之list详解

    C++数据结构之list详解

    list是一种序列式容器。list容器完成的功能实际上和数据结构中的双向链表是极其相似的,list中的数据元素是通过链表指针串连成逻辑意义上的线性表,也就是list也具有链表的主要优点,即:在链表的任一位置进行元素的插入、删除操作都是快速的
    2021-11-11
  • C语言自定义军旗游戏源码

    C语言自定义军旗游戏源码

    这篇文章主要为大家详细介绍了C语言自定义军旗游戏源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02

最新评论