首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

多線程編程入門:概念優勢與 C 語言 pthread 實現框架

     編輯:關於C語言

多線程編程入門:概念優勢與 C 語言 pthread 實現框架

單線程 vs 多線程

單線程:如工廠流水線,任務順序執行,前一道工序未完成後續阻塞。
多線程:將獨立任務拆分到多條執行流並行運行,互不阻塞。

多線程三大優勢

  1. 邏輯清晰:大流程拆解為小模塊,代碼結構簡潔易讀。
  2. 效率提升:多核 CPU 真並行,I/O 密集型任務重疊等待時間。
  3. 模塊化強:功能隔離,便於調試、維護、擴展。

pthread 創建線程完整框架

/**********************************************************************
 * 文件:ThreadCreate.c
 * 功能:演示多線程創建與基本同步
 **********************************************************************/
#include 
#include 
#include 

// 類型重定義
typedef signed int INT32;
typedef unsigned int UINT32;

#define THREAD_NUM 5 // 掃描線程數

// 線程函數聲明
void *ScanTask(void *pParam);
void *ProcessTask(void *pParam);

INT32 main() {
    pthread_t multi_handles[THREAD_NUM]; // 線程句柄數組
    pthread_t single_handle;
    INT32 ret;

    // 循環創建多個功能相同的線程 (傳遞索引作為參數)
    for (UINT32 i = 0; i < THREAD_NUM; i++) {
        ret = pthread_create(&multi_handles[i], NULL, ScanTask, (void *)i);
        if (ret != 0) {
            fprintf(stderr, "Create ScanTask %u failed: %d\n", i, ret);
            return -1;
        }
    }

    // 創建單個功能不同的線程
    ret = pthread_create(&single_handle, NULL, ProcessTask, NULL);
    if (ret != 0) {
        fprintf(stderr, "Create ProcessTask failed: %d\n", ret);
        return -1;
    }

    // 等待所有線程結束 (關鍵!否則主線程退出導致進程終止)
    for (UINT32 i = 0; i < THREAD_NUM; i++) {
        pthread_join(multi_handles[i], NULL);
    }
    pthread_join(single_handle, NULL);

    return 0;
}

// 掃描線程:參數為線程編號
void *ScanTask(void *pParam) {
    UINT32 thread_no = (UINT32)pParam;
    printf("Now into ScanTask[%u].\n", thread_no);
    // 實際掃描邏輯...
    return NULL;
}

// 處理線程:無參數
void *ProcessTask(void *pParam) {
    printf("Now into ProcessTask.\n");
    // 實際處理邏輯...
    return NULL;
}

pthread_create 參數詳解

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine)(void *), void *arg);
  • thread:輸出參數,返回線程 ID。
  • attr:屬性對象 (通常 NULL 使用默認屬性:非分離、默認棧大小、繼承調度策略)。
  • start_routine:線程入口函數,簽名固定 void *(*)(void *)。
  • arg:傳遞給入口函數的單個參數 (常用結構體指針傳多值)。
  • 返回值:0 成功,非零錯誤碼 (如 EAGAIN 資源不足, EINVAL 屬性無效)。

Linux 編譯鏈接關鍵

gcc -g -o ThreadCreate ThreadCreate.c -lpthread
# 必須顯式鏈接 -lpthread (或 -pthread),因 pthread 非默認庫

多線程編程避坑指南

  • 全局變量競爭:多線程讀寫共享變量必須加鎖 (pthread_mutex_t) 或用原子操作 (__sync_*/atomic_*)。
  • 線程分離:若不需 pthread_join 回收返回值,調用 pthread_detach 避免僵屍線程佔資源。
  • 棧大小:深遞歸/大局部數組需 pthread_attr_setstacksize 調大 (默認常 8MB)。
  • 取消點:長時間計算循環中插入 pthread_testcancel 響應取消請求。
  • 線程局部存儲 (TLS):pthread_key_create + pthread_setspecific/getspecific 實現線程私有全局變量。

推薦閱讀

《進程與線程的一個簡單解釋》 — 閮一峰,圖解進程/線程區別、操作系統調度、協程等核心概念。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved