2012-12-28 52 views
10

我在C中編寫了一個等待事件的程序,然後通過system()函數運行外部系統命令。C中的快速生產者/慢速消費者

while(true){ 
    wait_for_event(); 
    system("cmd"); 
} 

我對此有seriuos問題,cmd是一個沉重的命令,並需要幾秒鐘才能完成,我的應用程序錯過這一時間框架的一些事件。

所以我決定移動system功能,這是非常沉重的,到另一個程序,所以我改變了我的程序如下:

while(true){ 
    wait_for_event(); 
    write_to_fifo("cmd"); 
} 

並寫了另一個程序:

while(true){ 
    system(read_from_pipe()); 
} 

但它並沒有幫助,因爲如果生產者(第一個程序)比消費者(第二個程序)寫得更快,那麼消費者會遺漏一些數據!

有什麼辦法可以解決這個問題嗎?

+4

使用線程捕獲事件,將它們添加到隊列中,並讓您的消費者從該隊列中拉出。 – Falmarri

+0

是否可以使用多個線程來減輕消費者的負擔,同時讓生產者單線程?當然,這是一場失敗的戰鬥,但根據你的要求,它可能足以救你。如果額外線程仍然過多,您還應該查看數據存儲。 – pickypg

+0

你如何設置你的管道?當然,如果您持續獲得的數據超過您的處理數量,那麼某些內容將「給予」。但是完全有可能使用管道來緩慢處理大量數據。否則,它將無法執行'cat myprog.c | gcc -o myprog' - 它確實 - gcc有時非常慢,cat會盡可能快地將它推送到管道。 –

回答

8

你應該代碼恢復到原來的形態—就是一個單獨的程序調用第二程序—除了更換system(3)呼叫與電話popen(3)。現在調用程序可以將事件檢查的調用與來自外部程序的讀取行交錯。

Unix管道機制確保緩慢的使用者將導致快速生產者在管道滿時寫入時等待。

你也可能想看看進入fileno(3)功能,具有select(2)poll(2)爲了使從外部程序異步閱讀結合起來,使之能從未阻止調用程序。

+0

感謝您的及時響應。我不熟悉linux下的C編程,請給出示例代碼。謝謝 – Maryam

+0

哇!它就像一個魅力!謝謝 – Maryam

+0

你真的應該得到這個主題的書籍之一。一塊一塊地學習它有其重點,但是有一個你需要接受的格式,只有當你在短時間內學到很多東西時纔會發生。我推薦* W. Richard Stevens在Unix環境下的高級編程* 2/e。還有其他這樣的書。在本書的年齡不要被關閉。即使是第一版對於現代Linux編程仍然有95%的用處。內核API和C標準庫在那個時候並沒有改變那麼多。 –

2

如果你需要的只是事件的數量,你可以有一個全局計數器。爲了避免競爭條件,您可能需要使用信號量來代替。當然,你需要有兩個線程。

由於您的事件包含重要信息,因此可以使用列表(或具有足夠數量的插槽的陣列)來存儲傳入數據。您可以使用互斥鎖來保護此列表。

+0

不,事件有一些重要的數據,它們應該被處理並存儲在其他地方。 – Maryam