天天看點

Perl多程序與信号量

今天這裡就不多說什麼是多程序、什麼是多線程了,簡單來說目的都是充分利用硬體資源,最大化機器性能。

任何語言的新手在遇到多程序程式設計時,心裡往往會發怵,多程序好像很高大上、好複雜的樣子,其實不然。我們要區分多程序實作本身和多程序應用程式設計,多程序本身的實作确實是很複雜的,但是我們更多的是集中在多程序應用程式設計,這部分就比較簡單了。

話不多說,下面先看用perl實作的一個多程序程式設計例子。

上述例子中,實作多程序最關鍵的方法就是fork,其功能是将目前代碼完全拷貝一份,也就是形成兩份相同的程式:父程序和子程序。其中,在父程序中,fork的傳回值是子程序的程序号(大于0的值);而在子程序中,fork傳回值是0;fork失敗時傳回的值為負數。fork失敗的情況一般是資源耗盡,我自己在程式設計時遇到過幾次,都是fork太多的程序耗盡了系統資源。

通過以上三個傳回值,我們就能确定fork有沒有成功,以及成功時誰是父程序、誰是子程序,這樣就可以決定在父程序或者子程序中做什麼樣的操作。

例子中父、子程序都是循環輸出1000至1,同時給出父子程序提示資訊。

輸出結果如下:

簡單來講(我最喜歡簡單來講),子程序完成使命(死了),卻沒有被父程序回收(收屍),什麼作用都沒有了,卻還暫留在系統中,就像僵屍。程序變為僵屍程序時其所占用的資源都會被回收掉,是以不會造成太大的資源洩露,當然,程序本身的資訊(程序号,建立時間等)還是存在的。

一般情況是父程序比子程序提前結束并且沒有任何其它程序來回收子程序時就會産生僵屍程序,例如我們在程式中沒有指明父程序需要等待子程序全部結束并回收子程序時,子程序就會成為僵屍程序。

避免産生僵屍程序需要用到wait或者waitpid函數,這裡我使用的是<code>waitpid($pid,0)</code>函數。該函數的功能是等待$pid程序結束并回收它。

代碼如下:

不需要多麼仔細的觀察就能發現第一個樣例程式中,兩個程序是并行執行的,這或許正是我們使用程序的目的。但是,有些時候,比如說兩個程序都需要使用某個資源,而這個資源不能被兩個程序同時使用,是以我們希望這兩個程序串行執行。這個時候我們就需要使用鎖這種東西來確定程序同步。

在這裡,我使用了ipc的信号量,并讓信号量資源值為1,當資源值為1時,其作用相當于鎖。

linux系統中使用ipcs -a指令可以檢視目前系統中所有的信号量及共享記憶體段等使用。有些時候程式意外終止,信号量未釋放,那麼就可以使用該指令檢視信号量,并使用ipcrm -s semid移除用semid辨別的信号。

完整代碼如下:

輸出結果如下,可以看到,兩個程序時串行執行的,達到了程序同步的效果。

繼續閱讀