2011-03-10 20 views
2

我需要爲來自網絡套接字的大量數據實現一個簡單的「溢出到磁盤」層。我希望有兩個C FILE*流,一個由寫入文件的後臺線程使用,另一個由讀取它的前端線程使用。單個文件上兩個C FILE *流的一致性

兩個流這樣一個線程可在一個偏移來寫,而另一種是閱讀別處 - 不以鎖定並阻止其他線程。

會有分頁機制,所以讀/寫操作在隨機訪問的地點 - 不一定是連續的。

還有一點需要注意,這需要在Windows和Linux上運行。

的問題:fwrite的第一流返回之後,則寫入數據保證是立即可見對第二流的FREAD?

如果不是,我可以考慮哪些其他選項?


所以Posix的PREAD/PWRITE功能竟然是我所需要的。這裏是一個用於Win32的版本:

size_t pread64(int fd, void* buf, size_t nbytes, __int64 offset) 
{ 
    OVERLAPPED ovl; 
    memset(&ovl, 0, sizeof(ovl)); 
    *((__int64*)&ovl.Offset)=offset; 

    DWORD nBytesRead; 
    if (!ReadFile((HANDLE)_get_osfhandle(fd), buf, nbytes, &nBytesRead, &ovl)) 
     return -1; 

    return nBytesRead; 
} 

size_t pwrite64(int fd, void* buf, size_t nbytes, __int64 offset) 
{ 
    OVERLAPPED ovl; 
    memset(&ovl, 0, sizeof(ovl)); 
    *((__int64*)&ovl.Offset)=offset; 

    DWORD nBytesWritten; 
    if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, nbytes, &nBytesWritten, &ovl)) 
     return -1; 

    return nBytesWritten; 
} 

(謝謝大家對此的反饋 - 非常感謝)。

+0

這個數據每秒多少,處理它需要多長時間,驅動器有多快?在每個時間片上尋找光盤上文件不同部分的兩個線程可能會使硬盤驅動器像Mix-Master Mike一樣工作。你考慮過內存映射文件嗎? – gpcz 2011-03-10 02:05:01

+0

@gpcz:只有在一個真正破壞的操作系統中,寫入實際上會導致在底層存儲介質上尋找... – 2011-03-10 02:12:53

+0

@gpcz:在此之上會有一層分頁緩存(我簡化了問題)我並不擔心這一點。 – 2011-03-10 02:24:42

回答

2

這絕對不會給你想要的語義。如果你禁用了緩衝,那麼期望它可以正常工作可能是合理的,但我仍然認爲沒有任何保證。 Stdio/FILE真的不是像這樣的專門IO需求的正確工具。

POSIX通過文件描述符和pread/pwrite函數完成你想要的操作。我懷疑有一種Windows方式(或者你可以基於其他基礎的Windows原語來模擬它們),但我不知道它。

而且使用內存映射IO的Ben的建議是一個很好的一個,假設文件在您的地址空間適合。

+0

我正在尋找pread/pwrite,現在只需要一個適用於Windows的解決方案。最近我找到了重疊的IO,它允許指定偏移量,但我想要帶偏移量的同步IO。 – 2011-03-10 02:22:26

+0

@Brad:在Windows上,ju st使用'DuplicateHandle'。每個句柄都有自己的文件指針。 – 2011-03-10 02:28:27

+0

@Ben:你確定嗎?剛剛寫了一個快速測試應用程序,看起來像他們共享相同的文件指針。 – 2011-03-10 02:42:15

4

這聽起來很適合內存映射I/O。它保證一致,非常快速,並且跟蹤多個指針很簡單。

你需要不同的功能設置在不同的操作系統的內存映射,但(使用指針尊重)的實際I/O是完全可移植的。

  • 的Linux:openmmap
  • 的Windows:CreateFileMappingMapViewOfFile
+0

謝謝本。我曾考慮內存映射文件,但正如「R ..「有可能它不適合地址空間(實際上我發現真的很難相信,但這就是我被告知的) – 2011-03-10 02:21:04

+0

@Brad:內存映射創建一個」窗口「或」視圖「放入只代表文件一部分的文件中,地址空間的要求取決於視圖的範圍,查看整個文件最簡單,但如果文件很大,則需要一些額外的操作系統特定的代碼以管理一個較小的視圖 – 2011-03-10 02:24:14

+0

正確...我正在考慮MMF,但我需要管理文件的部分視圖 - 在這一點上,我意識到,我可能只是做自己的讀/寫,因爲它適合更好的我正在尋找pread/pwrite – 2011-03-10 02:28:51

相關問題