單線程:如工廠流水線,任務順序執行,前一道工序未完成後續阻塞。
多線程:將獨立任務拆分到多條執行流並行運行,互不阻塞。
/**********************************************************************
* 文件: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;
}
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 屬性無效)。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 響應取消請求。pthread_key_create + pthread_setspecific/getspecific 實現線程私有全局變量。《進程與線程的一個簡單解釋》 — 閮一峰,圖解進程/線程區別、操作系統調度、協程等核心概念。