Linux 多線程詳解

一、線程的概念

線程是操作系統調度的最小單位,它是進程中的一個執行單位。一個進程可以擁有多個線程,這些線程可以共享進程的資源,包括內存、文件等。線程之間的切換比進程之間的切換代價要小很多,也更加高效。在Linux系統中,線程的實現依賴於操作系統提供的POSIX線程庫(pthread)。

二、線程的創建和銷毀

線程的創建和銷毀是多線程編程的基本操作。在Linux系統中,線程的創建和銷毀都是通過pthread庫提供的函數實現的。例如,創建一個線程可以使用pthread_create函數,銷毀一個線程可以使用pthread_cancel函數。

void *thread_func(void *arg){
    printf("This is a pthread.\n");
    pthread_exit(NULL);
}
int main(){
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, thread_func, NULL);  //創建一個線程
    if(ret){
        printf("Create pthread error!\n");
        return -1;
    }
    pthread_join(tid, NULL);  //等待子線程結束
    return 0;
}

在上面的示例代碼中,pthread_t類型的tid變數儲存著新建線程的線程ID。pthread_create函數接受四個參數,第一個參數是指向新線程標識符的指針,第二個參數用於設置線程屬性,第三個參數是新線程運行的函數,第四個參數是傳給函數的參數。pthread_join函數用於等待子線程結束。

三、線程同步與互斥

線程同步與互斥是多線程編程中必須掌握的概念,它們是保證多個線程安全共享數據的重要手段。Linux系統提供了多種同步和互斥機制,其中最常用的是互斥鎖和條件變數。

pthread_mutex_t mutex;
pthread_cond_t cond;
void *thread_func(void *arg){
    // 模擬線程同步
    pthread_mutex_lock(&mutex);  // 加鎖
    pthread_cond_wait(&cond, &mutex);  // 等待條件變數的信號
    pthread_mutex_unlock(&mutex);  // 解鎖
    printf("Thread is over.\n");
    pthread_exit(NULL);
}
int main(){
    pthread_t tid;
    pthread_mutex_init(&mutex, NULL);  // 初始化互斥鎖
    pthread_cond_init(&cond, NULL);  // 初始化條件變數
    int ret = pthread_create(&tid, NULL, thread_func, NULL);  // 創建一個線程
    if(ret){
        printf("Create pthread error!\n");
        return -1;
    }
    // 模擬線程同步
    sleep(5);
    pthread_cond_signal(&cond); // 發送信號
    pthread_join(tid, NULL); // 等待子線程結束
    pthread_mutex_destroy(&mutex);  // 銷毀互斥鎖
    pthread_cond_destroy(&cond);  // 銷毀條件變數
    return 0;
}

在上面的示例代碼中,使用pthread_mutex_t定義了互斥鎖和pthread_cond_t定義了條件變數。pthread_mutex_lock和pthread_mutex_unlock函數用於加鎖和解鎖互斥鎖,pthread_cond_wait函數用於等待條件變數的信號,pthread_cond_signal函數用於發送信號。

四、線程池

線程池是提高多線程執行效率的重要手段,它可以使得多個線程共享一定數量的線程資源,避免了線程頻繁創建和銷毀的開銷。在Linux系統中,線程池的實現主要依賴於pthread庫提供的線程創建、銷毀和管理函數。

#define THREAD_NUM 5
#define QUEUE_SIZE 10
pthread_t threads[THREAD_NUM];
int queue[QUEUE_SIZE];
int front = 0, rear = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *worker_func(void *arg){
    int thread_id = *(int *)arg;
    while(1){
        pthread_mutex_lock(&mutex);  // 加鎖
        while(front == rear){  // 隊列為空,等待信號
            pthread_cond_wait(&cond, &mutex);
        }
        int task = queue[front++];  // 從隊列中取出任務
        printf("Thread %d get task %d.\n", thread_id, task);
        pthread_mutex_unlock(&mutex);  // 解鎖
        sleep(2);  // 模擬任務執行
    }
    pthread_exit(NULL);
}
int main(){
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    int tids[THREAD_NUM];
    for(int i = 0; i < THREAD_NUM; i++){
        tids[i] = i + 1;
        pthread_create(&threads[i], NULL, worker_func, &tids[i]);  // 創建線程
    }
    srand(time(NULL));
    for(int i = 0; i < 20; i++){  // 向隊列中添加任務
        pthread_mutex_lock(&mutex);  // 加鎖
        while((rear + 1) % QUEUE_SIZE == front){  // 隊列已滿,等待信號
            pthread_cond_wait(&cond, &mutex);
        }
        queue[rear] = rand() % 100;  // 添加任務
        rear = (rear + 1) % QUEUE_SIZE;
        printf("Task %d added to queue.\n", i);
        pthread_mutex_unlock(&mutex);  // 解鎖
        pthread_cond_signal(&cond);  // 發送信號
        sleep(1);
    }
    for(int i = 0; i < THREAD_NUM; i++){
        pthread_cancel(threads[i]);  // 結束線程
    }
    pthread_mutex_destroy(&mutex);  // 銷毀互斥鎖
    pthread_cond_destroy(&cond);  // 銷毀條件變數
    return 0;
}

在上面的示例代碼中,創建了一個固定大小的隊列來儲存任務,使用互斥鎖保證隊列的線程安全,使用條件變數通信。線程池中包括多個工作線程,它們都從隊列中獲取任務進行執行。主線程向隊列中添加任務,使用pthread_cond_broadcast函數給所有線程發送信號,線程池的核心在於阻塞等待隊列消息,並動態創建線程。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/249916.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 17:13
下一篇 2024-12-12 17:14

相關推薦

  • Python多線程讀取數據

    本文將詳細介紹多線程讀取數據在Python中的實現方法以及相關知識點。 一、線程和多線程 線程是操作系統調度的最小單位。單線程程序只有一個線程,按照程序從上到下的順序逐行執行。而多…

    編程 2025-04-29
  • 如何在Linux中添加用戶並修改配置文件

    本文將從多個方面詳細介紹在Linux系統下如何添加新用戶並修改配置文件 一、添加新用戶 在Linux系統下創建新用戶非常簡單,只需使用adduser命令即可。使用以下命令添加新用戶…

    編程 2025-04-27
  • 多線程和多進程的應用

    多線程和多進程是現代編程中常用的技術,可以提高程序的效率和性能。本文將從不同的角度對多線程和多進程進行詳細的介紹和應用。 一、多線程 vs 多進程 多線程和多進程都是為了實現程序並…

    編程 2025-04-27
  • 如何解決linux jar包 invalid or corrupt jarfile問題

    對於許多開發人員和系統管理員在Linux環境下使用Java開發過程中遇到的一個常見的問題是 invalid or corrupt jarfile(無效或損壞的jar文件)錯誤。當您…

    編程 2025-04-27
  • Python多線程模塊實踐

    本文將向大家介紹Python中的多線程模塊,並通過示例代碼來展示如何靈活使用線程提升程序的性能。同時,本文還將討論Python多線程模塊使用中可能遇到的一些問題及其解決方法。 一、…

    編程 2025-04-27
  • 在Linux上安裝JRE並配置環境變數

    本文將從以下幾個方面為您詳細闡述如何在Linux系統上,通過自己賬戶安裝JRE,並且配置環境變數。 一、安裝JRE 在進行安裝前,我們需要下載JRE的安裝包並解壓,可以從官方網站下…

    編程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用於Linux操作系統的一款照片管理器,它支持多種相機及存儲設備,並提供了一系列強大的工具,讓用戶可以方便地瀏覽、管理、編輯和導出照片。本文將從多個方面對GTKAM進行…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25

發表回復

登錄後才能評論