2011-08-18 81 views
1

在我的應用程序中,我有一個分叉子進程,說child1,並且這個子進程在磁盤上寫入一個巨大的二進制文件並退出。然後,父進程分離出另一個子進程child2,該進程讀入這個大文件以進行進一步處理。在Linux上的進程間共享數據

該文件轉儲和重新加載正在使我的應用程序變得緩慢,我正在考慮可能的完全避免磁盤I/O的方法 。我已經確定的可能的方法是ram-disk或tmpfs。 我可以以某種方式在我的應用程序中實現ram-disk或tmpfs嗎?或者有沒有其他的方式可以完全避免磁盤I/O,並且可靠地跨進程發送數據。

+0

只是爲了將更多的東西放在正確的角度看,父進程實際上分出了3-4個子進程寫入磁盤,然後這些文件被後續的子進程讀入。所有這些子進程不會同時存在,並在將數據寫入磁盤後退出。 – user900563

+0

由於涉及到很多流程,我認爲設置管道可能會變得過於複雜和脆弱。相反,如果我可以構建一個封裝的API來模擬磁盤以滿足我需要的幾件事,那就太酷了! – user900563

+0

爲什麼分叉?使用線程並將該文件保存在內存中。 – Matt

回答

3

如果兩個子進程不同時運行,管道或套接字將無法工作 - 它們的緩衝區對於「巨大的二進制文件」來說太小了,第一個進程將阻塞等待任何讀取數據。

在這種情況下,您需要某種共享內存。您可以使用SysV IPC共享內存API,POSIX共享內存API(在最近的Linux上內部使用tmpfs)或直接在tmpfs上使用文件(通常掛載在/ dev/shm,有時在/ tmp上)。

+0

是的,子進程不會同時運行,但父進程處於活動狀態直到最後一個子進程退出。我一直在考慮直接在tmpfs文件系統上使用文件,但不知道如何在程序中實現它們。任何指針? – user900563

0

生成兩個進程,讓他們通過套接字傳輸數據。 TCP最容易入門,但如果您想提高效率,請使用Unix Domain Sockets。這假定您不關心正在寫入磁盤本身的數據。

+0

實際上2個子進程並不是同時存在的。第一個完成工作,轉儲文件並退出,在此之後,下一個孩子分叉,加載這個文件並完成其餘的處理。我可以在parent-child1和parent-child2之間建立一個套接字嗎? – user900563

+0

讓他們同時跑步怎麼樣?它可能會大大減少總運行時間,作爲一項副作用。 –

0

您可以使用管道在進程之間傳遞數據。 Here是一個很好的概要和示例實現。

1

A named pipe正是你想要的。您可以將數據寫入它並從中讀取數據,就像它是一個文件一樣,但不需要將其存儲在磁盤上。

+0

爲什麼命名管道,當進程是從一個進程派生出來的,並且可以直接共享文件描述符? –

+0

@Jacek這是一個很好的觀點;你是對的。 –

1

您可以使用管道和套接字,並利用Linux內核的sendfile()splice()功能(它們可以避免數據複製)。

1

分叉,然後所有的孩子都能叉後使用之前創建一個匿名的共享內存區域:

char *shared = mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); 

要知道,共享內存時,你需要一些同步機制。實現這一點的一種方法是在共享內存區域內放置一個互斥鎖或信號量。

-1

如您案第一個孩子的過程child1在退出的child2到來之前存在這樣的socket通信,或者使用未命名管道不會幫助,

但共享內存將做的工作: 創建共享內存段在child1中具有讀取所有權限的權限並在該共享內存中執行文件轉儲任務 在child2中,將共享內存段附加到當前進程空間並讀取轉儲的數據。

+0

歡迎來到SO。請解釋如何解決問題並給出一些例子。你可以閱讀這個:http://stackoverflow.com/help/how-to-answer – Sebi