Linux下Python與C程序進程間通信

轉自:kevin1985.blog.chinaunix.net


這幾天做了一點事情,略微有些收穫,跟大家分享一下

Python大家應該比較熟悉,很好的一門語言,最近幾年一直很流行,尤其是在外企,比較有名的IT公司幾乎毫無例外的都使用python,像Intel, Marvell, Cisco, EMC等等。

我也認爲這門語言很優秀,首先是語法簡單,學起來很快,如果有c++經驗的話幾天就上手了,

其次是開源,那就意味着你可以再遵循GPL的條件下隨意分發和使用。

還有就是維護起來容易,據統計Python代碼比其他代碼維護成本至少要少一半

好了,不說廢話了,記得有次參加Ubuntu的發佈會,有位大牛說過一句話“人生苦短,請用Python”


但是一些比較底層的東西Python是無能爲力的,比如說Linux下的文件系統啊,設備驅動啊等等,跟C比起來效率還是差一截,畢竟這個世上沒有萬能的工具,

但是我們可以將這幾個工具組合以發揮他們最大的威力,靠近底層的,效率要求比較高的我們用c來實現,c短小精悍,而上層點的比如UI部分我們則可以用Python來實現,

然後用Python來調用c程序,好了,這裏就是本文的關鍵了,怎麼讓C程序和Python通信呢?


可能上面講的很多人還不是很明白,上個例子吧

比如我們要操作磁盤設備文件(/dev/sdb1),然後對這個文件進行寫,直到將其寫滿位置,一般這種文件都很大,如果用python來做的話效率勢必很低,我們

只有用c來實現,具體的c程序的實現部分比較簡單,感興趣的可以自己做個實驗,上層UI部分我們用Python實現。


現在假設我們已經用C程序實現了,並編譯生成一個可執行文件,名爲“DiskErase”,

我們需要實現的是DiskErase怎麼和Python程序通信,以讓UI知道當前寫了多少字節到/dev/sdb1中,然後更新當前進度條。

在Python中我們很容易通過System("./DiskErase")來實現對DiskErase的調用,但是這樣是不能讓上層Pthon程序和DiskErase通信的,

有人說Python中有個popen(“./DiskErase"),然後就可以通信了, 不錯,這樣只能Python程序是可以得到DsikErase的輸出(printf之類的東西),

但是Python會等待DiskErase執行完畢纔會再繼續執行下去,那麼我們UI中的進度條怎麼可能實時更新了,所以這種方法當然不行。

Python中還有個專門用於進程間通信的模塊,名叫subprocess,可以在python程序中將標準輸出作爲管道,這裏的DiskErase輸出到標準輸出的東西我們都可以通過

讀管道來獲得,所以可以實時獲得DiskErase的輸出,更新UI部分的精度條,這樣就實現了C程序和Python的進程間通信,下面是Python程序的部分關鍵源碼:

## This funciton is to excute the cmd in order to fork a new process by subprocess.Popen ###
def excute_cmd(self, cmd = []):                                            //cmd = ['xad_hd', '-s', str(standard), '-g', self.get_disk(widget)]    cmd 是一個列表,可以以參數傳遞過去
percentage = 0                                                                 // 列表第一項是C程序的可執行文件,後面的是一些參數
sp = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)   //將標準輸出和標準錯位重定向爲管道
    while True:
        time.sleep(0.5) 
        sp.send_signal(signal.SIGUSR1)            //每0.5秒python程序向c程序發送一次信號, c程序對應的信號處理程序中向標準輸出打印想要傳遞的數據
message = sp.stdout.readline()            //讀管道
.........                                             //對從管道讀到的數據進行處理




發佈了43 篇原創文章 · 獲贊 11 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章