Python os.fork() 依賴作業系統系統呼叫建立子進程,子進程為父進程的鏡像副本,但擁有獨立的虛擬記憶體空間(Copy-on-Write 機制)。本文解析 fork 行為、返回值語義、進程間獨立性與調度不確定性。
核心程式碼範例
import os
def child():
print 'A new child:', os.getpid()
print 'Parent id is:', os.getppid()
os._exit(0) # 直接退出,不執行清理
def parent():
while True:
newpid = os.fork()
print newpid
if newpid == 0:
child()
else:
pids = (os.getpid(), newpid)
print "parent:%d, child:%d" % pids
print "parent's parent:", os.getppid()
if raw_input() == 'q':
break
parent()
fork() 返回值語義
| 返回值 | 所在進程 | 含義 |
| 0 | 子進程 | 表示「我是子進程」 |
| >0 (PID) | 父進程 | 子進程的 Process ID |
| <0 | 父進程 | 建立失敗(資源不足等) |
記憶體空間獨立性
- 子進程獲得父進程記憶體的**邏輯副本**(Copy-on-Write)
- 修改變數不影響彼此
- 檔案描述符表被複製,共享開啟檔案的 offset
執行順序不確定性
父子進程執行順序由作業系統排程器決定,屬**非確定性**:
- 可能先執行父進程的
else 區塊
- 可能先執行子進程的
child()
- 類似多執行緒的競爭條件,但進程間無共享記憶體
關鍵函數說明
os.getpid():取得目前進程 ID
os.getppid():取得父進程 ID
os._exit(0):立即終止進程,不執行 atexit、finally、緩衝區刷新(子進程常用)
sys.exit() / exit():正常退出,執行清理(父進程適用)
實際輸出範例(順序不固定)
12345
parent:12344, child:12345
parent's parent: 12343
A new child: 12345
Parent id is: 12344
適用場景與替代方案
| 場景 | 推薦方案 |
| 簡單平行化、Unix 傳統 | os.fork() |
| 跨平台、高階 API、進程池 | multiprocessing.Process |
| 需共享記憶體、頻繁通訊 | threading / multiprocessing.Value/Manager |
| 非阻塞 I/O、高併發 | asyncio / gevent |
注意事項
- Windows 不支援
os.fork()(無此函數)
- fork 後多執行緒狀態複雜,建議僅在單執行緒程式使用
- 大量 fork 可能耗盡 PID 或記憶體,需控制併發數
- 孤兒進程由 init (PID 1) 收養,殭屍進程需
wait() 清理
- 上一篇文章: Python 字典刪除元素完整指南:del、pop、clear 與最佳實踐
- 下一篇文章: Python 生成器實現協程並發:yield、greenlet、gevent 核心原理與實戰
Copyright ©
程式碼之家 All Rights Reserved