Synchronization
將標準輸入複製到標準輸出和標準錯誤,但以同步方式
我需要複製生產者的標準輸出並以同步方式將其提供給兩個消費者。
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 的建議),
- 你檢查消費者的處理進度,看看他們是否已經消費了輸入行(這需要消費者的回饋或輸出,可能存在也可能不存在,可能處理也可能不可行)。
第一個解決方法需要一個適當的下限來估計輸入數據的處理時間,第二個解決方法需要來自消費者的某種回饋。