Synchronization

將標準輸入複製到標準輸出和標準錯誤,但以同步方式

  • September 6, 2015

我需要複製生產者的標準輸出並以同步方式將其提供給兩個消費者。

                       consumer 1
producer | duplicator | 
                       consumer 2

這可以通過 tee 輕鬆實現:

(cat file.txt | tee /dev/stderr | ./consumer1.py ; ) 2>&1 | ./consumer2.py

或通過命名管道:

mkfifo myfifo
cat file.txt | tee myfifo | ./consumer1.py | ./consumer2.py < myfifo

或者最後你可以編寫一個 dup.c 程序來做同樣的工作:

#include <stdio.h>
int main()
{
   char *line = NULL;
   size_t size;
   while (getline(&line, &size, stdin) != -1) {
       fprintf(stdout, "%s", line);
       fprintf(stderr, "%s", line);
   }
   return 0;
}

進而:

(cat file.txt | ./dup | ./consumer1.py ; ) 2>&1 | ./consumer2.py

但是,如果消費者 1 比消費者 2 快,我們就有問題了。例如,消費者 1 已經在第 50,000 行,而消費者 2 在第 17,000 行。

對於我的系統**,我需要兩個消費者都在同一條線上,因此需要限制更快的消費者**。我知道通過 Linux 標準工具這可能是不可能的。但是,至少如果我們使用 dup.c 方法,它應該是可能的。任何建議如何做到這一點?謝謝!

沒有通用的方法來完成你想要的。

基本問題是管道是單向的東西,生產者完全不知道消費者的目前狀態,以及發送到管道的數據是否已經被消費。

因此,有兩種方法可以解決此限制,並且都需要有關數據和消費者的先驗知識:

  • 您使生產(或從原始生產者到消費者管道的傳輸)如此緩慢,以至於消費者始終保持同步,即在每條線被發送以供消費之後,您等待如此之久,以至於消費者 100% 肯定已經完成在發送下一行時進行處理(類似於 TiberiusKirk 的建議),
  • 你檢查消費者的處理進度,看看他們是否已經消費了輸入行(這需要消費者的回饋或輸出,可能存在也可能不存在,可能處理也可能不可行)。

第一個解決方法需要一個適當的下限來估計輸入數據的處理時間,第二個解決方法需要來自消費者的某種回饋。

引用自:https://unix.stackexchange.com/questions/227851