2011-01-19 168 views
0

我有一種情況,我有一個複雜消息的傳入流,它們在以簡化格式傳遞給實際處理程序之前需要進行一些處理。控制文件描述符的準備

我想使用一個FIFO文件描述符,一個線程從一端填充它,另一個線程從另一端讀取。現在我想要的那種行爲:閱讀線程正在等待select(),我想保證在喚醒時有一個完整的包,可以通過調用read()來讀取,即我想避免由於緩衝區大小而導致碎片重新組裝(軟件包保證低於內核到用戶空間的緩衝區傳遞限制)。

我想知道是否有一種配置FIFO的方式,以便我可以手動定義文件描述符何時準備就緒,即生產者已成功編寫完整軟件包時,我想要有一個向讀取結束(通過文件描述符)發送信號的方式是讀取已準備就緒。有沒有一種方法可以通過ioctl()來實現,或者除了提供這種行爲的FIFO之外還有一些抽象(在Linux世界中)? (我知道pthread和條件變量,但我想生產者和消費者之間的耦合被限制到共享文件描述。)

回答

1

我想知道是否有在這樣的配置FIFO的方式一種我可以手動定義文件描述符何時準備就緒的方式

沒有這種方法。

你必須。

  • 定義某種消息框架。例如在消息前添加消息長度,或者用換行符分隔它們(因爲消息中不會出現換行符)。對於換行符分隔的消息,除非您依賴select()來複用多個流或提供超時,否則您可能可以將filedescriptor包裝在FILE *和fgets()中。
  • 準備處理read()或類似的讀取1消息,少於1條消息或超過1條消息 - fifo只是一個字節流,因此該層沒有消息邊界。
  • 根據您決定如何分開它們,解析出您閱讀過的郵件。

另一種方法是總是發送一個固定長度的消息,所以你總是知道多少閱讀拿到1個消息,或者使用AF_UNIX數據報套接字 - 只要你可以定義一個合理的最大尺寸信息。

2

嘗試socketpair()而不是pipe()/mknod(S_IFIFO)

套接字對可以在域AF_UNIX進行與SOCK_STREAM類型(基於流的,您的使用將需要幀化/重新裝配),SOCK_DGRAM(數據報爲基礎,將不被分段或合併的),或SOCK_SEQPACKET(基於記錄,可能被分割但不合並)。