目錄
引言
基本概念
1. 進程(Process)
2. 線程(Thread)
線程編程實戰
1. 常見線程庫
2. 合理設置線程數
3. pthread 創建線程
線程同步機制
1. 互斥鎖 pthread_mutex_t
2. 條件變量 pthread_cond_t
3. 讀寫鎖 pthread_rwlock_t
進程的創建與控制
1. fork
2. exec
3. system
4. popen 管道讀取輸出
進程間通信 IPC 詳解
1. 方式對比表:
2. 信號 signal
3. 共享內存 POSIX
總結
引言
本文深入探討了 C 語言中多線程編程、進程間通信(IPC)機制的底層實現,涵蓋線程同步、信號量、互斥鎖、共享內存等關鍵知識,并通過實際任務案例帶你走進操作系統世界中的“線程宇宙”
基本概念
1. 進程(Process)
程序的一次執行過程,是操作系統進行資源分配的最小單位。
-
一個程序至少有一個進程。
-
每個進程有自己的 地址空間、資源集合 和 執行上下文。
進程分類:
-
前臺進程
-
后臺進程
-
服務進程(如守護進程)
運行在服務器上一般都是守護進程。
2. 線程(Thread)
線程是進程中獨立的執行單元,是程序執行的最小單位。
-
一個進程至少有一個主線程(main thread)。
-
多個線程共享該進程的地址空間和資源。
-
線程擁有自己的 棧空間 和 寄存器上下文。
線程編程實戰
1. 常見線程庫
-
POSIX Thread:
pthread
(C語言中最常用) -
OpenMP:并行處理,適合 C/C++
-
C++11
std::thread
(不在本文范圍)
2. 合理設置線程數
// CPU 密集型:核心線程數 ≈ CPU數 + 1
// IO 密集型:核心線程數 ≈ ((線程等待時間 / 線程CPU時間) + 1) * CPU數
3. pthread 創建線程
#include <pthread.h>void *thread_func(void *arg) {printf("This is a new thread\n");return NULL;
}int main() {pthread_t tid;pthread_create(&tid, NULL, thread_func, NULL);pthread_join(tid, NULL); // 等待線程結束return 0;
}
線程同步機制
線程同時訪問共享資源時容易引發競態條件,需進行同步。
1. 互斥鎖 pthread_mutex_t
-
pthread_mutex_init
-
pthread_mutex_lock
-
pthread_mutex_unlock
-
pthread_mutex_destroy
2. 條件變量 pthread_cond_t
用于線程間等待與喚醒的機制。
pthread_cond_t cond;
pthread_mutex_t mutex;pthread_cond_init(&cond, NULL);
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex); // 釋放鎖并阻塞
pthread_cond_signal(&cond); // 喚醒一個線程
pthread_mutex_unlock(&mutex);
3. 讀寫鎖 pthread_rwlock_t
適用于讀多寫少的場景。
pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock, NULL);pthread_rwlock_rdlock(&rwlock); // 讀鎖
pthread_rwlock_unlock(&rwlock);pthread_rwlock_wrlock(&rwlock); // 寫鎖
pthread_rwlock_unlock(&rwlock);
進程的創建與控制
1. fork
克隆當前進程,創建子進程。
pid_t pid = fork();
if (pid == 0) {// 子進程
} else {// 父進程
}
2. exec
用新程序替換當前進程的映像。
execl("/bin/ls", "ls", "-l", NULL);
3. system
執行 shell 命令,本質是 fork + exec 的封裝。
system("ls -l");
4. popen
管道讀取輸出
進程間通信 IPC 詳解
1. 方式對比表:
方式 | 特點 | 是否跨進程 | 是否阻塞 | 適用場景 |
---|---|---|---|---|
管道 | 簡單易用 | 是 | 是 | 父子進程 |
信號 | 異步通知機制 | 是 | 否 | 異常處理 |
信號量 | 原子性控制 | 是 | 是 | 多進程同步 |
共享內存 | 訪問速度最快 | 是 | 否 | 大數據共享 |
消息隊列 | 異步通信 | 是 | 否 | 有序通信 |
套接字 | 網絡/本地通信 | 是 | 是/否 | 客戶端/服務端通信 |
2. 信號 signal
#include <signal.h>void handler(int sig) {printf("Caught signal %d\n", sig);
}int main() {signal(SIGINT, handler); // 注冊 ctrl+C 的信號處理while (1) pause();
}
3. 共享內存 POSIX
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>int fd = shm_open("/shm_name", O_CREAT | O_RDWR, 0666);
ftruncate(fd, 4096);
void *ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);// 寫入共享內存
strcpy((char*)ptr, "Hello from shared memory");munmap(ptr, 4096);
close(fd);
shm_unlink("/shm_name");
總結
通過本文的學習,我們系統掌握了 C 語言中進程與線程的基本概念、線程創建與同步的編程方法,以及多種進程間通信(IPC)機制,包括信號、共享內存、信號量等。進程負責資源的獨立管理,線程則提供更輕量級的并發執行方式;同步機制確保了多線程環境下數據的一致性,而 IPC 則使得多個進程間能夠高效協作與通信。結合實際案例,我們不僅加深了對操作系統底層原理的理解,也提升了并發編程與系統開發的能力。對于從事系統編程、服務器開發或學習操作系統的同學,這些內容都是必不可少的核心知識。
更多代碼可以觀看:Niuer_C: C語言學習?0711-0721