亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語言線程池的常見實現(xiàn)方式詳解

 更新時間:2025年01月06日 14:09:46   作者:半桶水專家  
本文介紹了如何使用 C 語言實現(xiàn)一個基本的線程池,線程池的實現(xiàn)包括工作線程、任務隊列、任務調(diào)度、線程池的初始化、任務添加、銷毀等步驟,感興趣的朋友跟隨小編一起看看吧

在 C 語言中,線程池通常通過 pthread 庫來實現(xiàn)。以下是一個詳細的說明,介紹了 C 語言線程池的常見實現(xiàn)方式,包括核心概念、實現(xiàn)步驟和具體的代碼示例。

1. 線程池的基本結(jié)構(gòu)

線程池的核心概念是有一個固定數(shù)量的線程等待執(zhí)行任務。任務通常通過任務隊列傳遞,線程從隊列中取出任務并執(zhí)行。線程池的主要目標是提高資源利用率,避免頻繁地創(chuàng)建和銷毀線程。

線程池的主要組件:

  • 任務結(jié)構(gòu):保存任務信息,比如任務的函數(shù)指針和參數(shù)。
  • 任務隊列:用于存放待處理的任務。當所有工作線程都在忙時,新提交的任務會被放到隊列中,直到線程空閑出來。
  • 線程池控制:管理線程池的線程,調(diào)度任務的分發(fā),維護任務隊列。

2. 線程池的實現(xiàn)步驟

以下是實現(xiàn)一個簡單線程池的基本步驟:

初始化線程池

創(chuàng)建一定數(shù)量的線程,并使它們處于等待狀態(tài)。

創(chuàng)建一個任務隊列,用來存儲待執(zhí)行的任務。

任務提交

用戶提交任務到線程池,線程池會把任務放入任務隊列中,等待工作線程去執(zhí)行。

工作線程

工作線程從任務隊列中取出任務并執(zhí)行。

如果沒有任務,線程會阻塞,直到有任務提交到任務隊列。

關閉線程池

關閉線程池時,需要確保所有任務完成后再銷毀線程池,并且釋放所有資源。

3. 線程池的核心數(shù)據(jù)結(jié)構(gòu)

任務結(jié)構(gòu): 每個任務通常包括任務的執(zhí)行函數(shù)和任務的參數(shù)。

typedef struct {
    void (*routine)(void *arg);  // 任務執(zhí)行的函數(shù)
    void *arg;                   // 傳遞給任務函數(shù)的參數(shù)
} task_t;

線程池結(jié)構(gòu): 線程池需要包含任務隊列、線程數(shù)組、線程數(shù)量、鎖以及條件變量等。

typedef struct {
    pthread_t *threads;           // 工作線程數(shù)組
    task_t *task_queue;           // 任務隊列
    int queue_size;               // 隊列大小
    int head, tail;               // 隊列頭尾索引
    int thread_count;             // 線程池中的線程數(shù)
    pthread_mutex_t lock;        // 鎖,保護任務隊列
    pthread_cond_t cond;         // 條件變量,喚醒工作線程
    int shutdown;                 // 是否關閉線程池
} thread_pool_t;

4. 線程池的詳細實現(xiàn)

下面是一個完整的線程池實現(xiàn),包括初始化、任務提交、任務執(zhí)行和銷毀。

4.1 初始化線程池

首先需要創(chuàng)建線程池,并初始化必要的數(shù)據(jù)結(jié)構(gòu)。

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
typedef struct {
    void (*routine)(void *arg);  // 任務執(zhí)行的函數(shù)
    void *arg;                   // 傳遞給任務函數(shù)的參數(shù)
} task_t;
typedef struct {
    pthread_t *threads;           // 工作線程數(shù)組
    task_t *task_queue;           // 任務隊列
    int queue_size;               // 隊列大小
    int head, tail;               // 隊列頭尾索引
    int thread_count;             // 線程池中的線程數(shù)
    pthread_mutex_t lock;        // 鎖,保護任務隊列
    pthread_cond_t cond;         // 條件變量,喚醒工作線程
    int shutdown;                 // 是否關閉線程池
} thread_pool_t;
void *worker(void *arg) {
    thread_pool_t *pool = (thread_pool_t *)arg;
    while (1) {
        pthread_mutex_lock(&pool->lock);
        while (pool->head == pool->tail && !pool->shutdown) {
            pthread_cond_wait(&pool->cond, &pool->lock);  // 等待任務
        }
        // 檢查是否關閉線程池
        if (pool->shutdown) {
            pthread_mutex_unlock(&pool->lock);
            break;
        }
        task_t task = pool->task_queue[pool->head];  // 獲取任務
        pool->head = (pool->head + 1) % pool->queue_size;  // 隊列中移除任務
        pthread_mutex_unlock(&pool->lock);
        task.routine(task.arg);  // 執(zhí)行任務
    }
    pthread_exit(NULL);
}
void thread_pool_init(thread_pool_t *pool, int thread_count, int queue_size) {
    pool->threads = (pthread_t *)malloc(thread_count * sizeof(pthread_t));
    pool->task_queue = (task_t *)malloc(queue_size * sizeof(task_t));
    pool->queue_size = queue_size;
    pool->head = pool->tail = 0;
    pool->thread_count = thread_count;
    pool->shutdown = 0;
    pthread_mutex_init(&pool->lock, NULL);
    pthread_cond_init(&pool->cond, NULL);
    // 創(chuàng)建線程
    for (int i = 0; i < thread_count; i++) {
        pthread_create(&pool->threads[i], NULL, worker, pool);
    }
}

4.2 提交任務

當用戶需要執(zhí)行某個任務時,任務會被加入任務隊列,等待線程執(zhí)行。

void thread_pool_add_task(thread_pool_t *pool, void (*routine)(void *), void *arg) {
    pthread_mutex_lock(&pool->lock);
    // 檢查任務隊列是否滿
    if ((pool->tail + 1) % pool->queue_size != pool->head) {
        pool->task_queue[pool->tail].routine = routine;
        pool->task_queue[pool->tail].arg = arg;
        pool->tail = (pool->tail + 1) % pool->queue_size;  // 更新隊列尾部
        pthread_cond_signal(&pool->cond);  // 喚醒一個工作線程
    }
    pthread_mutex_unlock(&pool->lock);
}

4.3 關閉線程池

關閉線程池時,需要等待所有線程處理完任務后才能銷毀線程池??梢酝ㄟ^設置 shutdown 標志來通知線程池停止。

void thread_pool_destroy(thread_pool_t *pool) {
    pthread_mutex_lock(&pool->lock);
    pool->shutdown = 1;
    pthread_cond_broadcast(&pool->cond);  // 喚醒所有線程,確保線程能夠退出
    pthread_mutex_unlock(&pool->lock);
    // 等待所有線程退出
    for (int i = 0; i < pool->thread_count; i++) {
        pthread_join(pool->threads[i], NULL);
    }
    free(pool->threads);
    free(pool->task_queue);
    pthread_mutex_destroy(&pool->lock);
    pthread_cond_destroy(&pool->cond);
}

4.4 示例任務函數(shù)

用戶可以定義自己的任務函數(shù),傳遞參數(shù),并在任務函數(shù)中執(zhí)行實際的工作。

void print_hello(void *arg) {
    printf("Hello, %s!\n", (char *)arg);
}
int main() {
    thread_pool_t pool;
    thread_pool_init(&pool, 4, 10);  // 創(chuàng)建一個線程池,包含4個線程和10個任務隊列
    for (int i = 0; i < 5; i++) {
        char *name = malloc(10);
        sprintf(name, "Task %d", i + 1);
        thread_pool_add_task(&pool, print_hello, name);
    }
    sleep(1);  // 等待任務執(zhí)行
    thread_pool_destroy(&pool);  // 銷毀線程池
    return 0;
}

5. 線程池的調(diào)優(yōu)和優(yōu)化

在實際應用中,線程池的性能可以通過以下幾個方面進行調(diào)優(yōu)和優(yōu)化:

  • 最大線程數(shù)和最小線程數(shù):為了避免線程過多導致的資源競爭,可以設置最小線程數(shù)和最大線程數(shù)。
  • 任務隊列長度:任務隊列的長度要適中。過長的隊列可能導致任務過度堆積,過短的隊列則可能導致線程池無法充分利用資源。
  • 動態(tài)線程調(diào)整:根據(jù)系統(tǒng)負載動態(tài)增加或減少線程數(shù)量,能夠提高系統(tǒng)的效率和響應速度。
  • 任務超時機制:為了防止某些任務長時間占用線程,線程池可以設置任務的超時機制,當任務超時后放棄執(zhí)行或重新調(diào)度。

總結(jié)

本文介紹了如何使用 C 語言實現(xiàn)一個基本的線程池。線程池的實現(xiàn)包括工作線程、任務隊列、任務調(diào)度、線程池的初始化、任務添加、銷毀等步驟。通過這種方式,可以在多任務、高并發(fā)的場景中有效地管理線程,減少線程創(chuàng)建和銷毀的開銷,提高系統(tǒng)的效率。

到此這篇關于C語言線程池的常見實現(xiàn)方式詳解的文章就介紹到這了,更多相關C語言線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用C++將yolov8 onnx格式轉(zhuǎn)化為tensorrt格式

    使用C++將yolov8 onnx格式轉(zhuǎn)化為tensorrt格式

    這篇文章主要為大家詳細介紹了如何使用C++將yolov8 onnx格式轉(zhuǎn)化為tensorrt格式,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2024-11-11
  • 虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程

    虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程

    虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程,需要的朋友可以參考下
    2013-02-02
  • C++中4種強制類型轉(zhuǎn)換的區(qū)別總結(jié)

    C++中4種強制類型轉(zhuǎn)換的區(qū)別總結(jié)

    C++風格的類型轉(zhuǎn)換提供了4種類型轉(zhuǎn)換操作符來應對不同場合的應用。下面這篇文章主要給大家介紹了C++中4種強制類型轉(zhuǎn)換的區(qū)別,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • C++中memcpy和memmove的區(qū)別總結(jié)

    C++中memcpy和memmove的區(qū)別總結(jié)

    這篇文章主要介紹了C++中memcpy和memmove的區(qū)別總結(jié),這個問題經(jīng)常出現(xiàn)在C++的面試題目中,需要的朋友可以參考下
    2014-10-10
  • OpenCV實現(xiàn)人臉檢測

    OpenCV實現(xiàn)人臉檢測

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)人臉檢測的相關資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言MFC導出dll回調(diào)函數(shù)方法詳解

    C語言MFC導出dll回調(diào)函數(shù)方法詳解

    這篇文章主要為大家介紹了C語言MFC導出dll回調(diào)函數(shù)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • C++變量引用的概念介紹

    C++變量引用的概念介紹

    這篇文章主要介紹了C++變量引用的概念介紹,簡單提到了與指針概念的不同,通過代碼場景分析給大家介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • C++定時器實現(xiàn)和時間輪介紹

    C++定時器實現(xiàn)和時間輪介紹

    這篇文章主要介紹了C++定時器實現(xiàn)和時間輪介紹,定時器可以由很多種數(shù)據(jù)結(jié)構(gòu)實現(xiàn),比如最小堆、紅黑樹、跳表、甚至數(shù)組都可以,其本質(zhì)都是拿到最小時間的任務,然后取出該任務并執(zhí)行,更多相關內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-09-09
  • C++11中l(wèi)ambda、std::function和std:bind詳解

    C++11中l(wèi)ambda、std::function和std:bind詳解

    大家都知道C++11中增加了許多的新特性,下面在這篇文中我們就來聊一下lambda表達式,閉包,std::function以及std::bind。文中介紹的很詳細,相信對大家具有一定的參考價值,有需要的朋友們下面來一起看看吧。
    2017-01-01
  • 詳解Dijkstra算法之最短路徑問題

    詳解Dijkstra算法之最短路徑問題

    Dijkstra(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計算一個節(jié)點到其他所有節(jié)點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。本文將介紹其原理,并用C++實現(xiàn)
    2021-06-06

最新評論