這幾天,由於工作原因,需要將一個php寫的背景程式重串列執行改成並存執行。這樣必然涉及到多線程/多進程相關技術。PHP貌似沒有成熟的多線程機制,而有相對成熟的多進程機制。多進程編程,必然涉及到IPC(Inter-Process Communication)。PHP的IPC技術還是相當多的,可以在php原始碼目錄下(PHP_SRC/ext)看到sysvshm,sysvsem,sysvmsg,shmop等擴充,這些都可以用於IPC,下面簡單介紹一下:
pcntl - 提供進程相關操作函數 sysvsem - 訊號量,全稱為system V semphore,可以用於限制訪問共用資源的進程數目,一般設定為1,當作互斥鎖使用 sysvshm - 共用記憶體,全稱system V shared memory,用於提供共用記憶體機制,特點是省去了客戶代碼序列化和還原序列化的麻煩,變數層級的存取控制,十分好用,屬於菜鳥使用的方式。 shmop - 共用記憶體操作擴充,與sysvshm的區別在於是位元層級的控制,需要手動序列化和還原序列化,但是如果緊缺使用,記憶體使用量率比sysvshm高,屬於高手進階方式。 sysvmsg - 訊息佇列,一種特殊的共用記憶體,具體使用可以參見這裡。
下面是使用sysvsem的列子,作為備忘,具體的內容參見代碼,這裡只提出幾個關鍵需要注意的地方:
shm_attach和sem_get的方法的key需要與主進程ID關聯,避免兩個組件同時運行打攪,因為共用記憶體和訊號量是系統層級的資源,進程之間會公用,如果不處理,會導致多個執行個體之間出現混亂。 父進程在等待子進程時,忙等會消耗大量CPU,採用sleep的方式,可以避免忙等。 父進程等待子進程最好有逾時機制,避免無限制等待 子進程邏輯必須在規定的地方退出,不能執行父進程的代碼,否則會混亂。常見的方式是用try catch包裹子進程的邏輯,抓到異常後,退出。
0) { echo "{$nPID} exit\n"; ++$n; } sleep(1); // 避免忙等} // clear shm//shm_detach($nShmID);sem_remove($nSemID);shm_remove($nShmID);echo "finished\n";?>
相關資料
PHP IPC: http://blog.csdn.net/eroswang/article/details/2195260
PHP IPC system v 和shmop: http://liangfen1224.blog.163.com/blog/static/72377647201111163317325/