嚴格說來,同一進程內的線程不需要通信機制,因為它們天然共享進程地址空間(全局變量、堆、代碼、打開的文件描述符)。本文通過一個對比實驗,直觀展示進程隔離與線程共享的本質差異。
int data = 1 作為共享資源。fork)。PID: 4394 -> Father Process running old data=1, new data=2 // 父進程修改 1→2 PID: 4395 -> Son Process running old data=1, new data=3 // 子進程看到初始值1,修改 1→3(獨立副本!) Son process finished: PID=4395 Create first thread by 4394 TID: 3075603264 old data=2, new data=4 // 線程1看到父進程修改後的值2,修改 2→4 Create second thread by 4394 TID: 3075603264 old data=4, new data=5 // 線程2看到線程1修改後的值4,修改 4→5
| 場景 | 數據可見性 | 原因 |
|---|---|---|
| 父進程 → 子進程 | 不可見 | fork 復制地址空間(Copy-on-Write),子進程擁有獨立 data 副本 |
| 子進程 → 父進程 | 不可見 | 同理,修改各自副本 |
| 父進程 → 線程1 | 可見 | 線程共享父進程地址空間,直接訪問同一 data |
| 線程1 → 線程2 | 可見 | 同一地址空間,線程1寫入,線程2立即讀到新值 |
線程間傳遞數據的模式:
pthread_key_create/pthread_setspecific 實現線程私有全局變量。因進程隔離,必須借助內核:
shmget/mmap 映射同一物理頁,**最快IPC**,但需自行同步(信號量/互斥量置於共享區)。sigaction 可傳遞 sigval (Linux實時信號)。這個實驗揭示了並發編程最核心的真相:進程隔離靠內核,線程共享靠硬件(MMU頁表共享)。理解這一點,選擇進程還是線程、設計通信同步方案,就有了堅實的理論基石。