首頁 > 軟體

C++單例模式實現執行緒池的範例程式碼

2023-08-28 18:05:31

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 runningn", *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++單例模式實現執行緒池內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com