簡體   English   中英

C&bash重定向過程通信

[英]C & bash redirection processus communication

看看這個bash:

mkfifo fifo
./processA <fifo | processB >fifo

在我的進程A中,我生成一個文件,該文件由進程B發送。然后,我想處理processB的結果。

因此,在AI中,只需使用printfs將信息發送到B到std即可。 然后,我創建一個僅讀取(stdin)的線程。 創建此線程后,我通過printf將信息發送到B。

我不明白為什么整個過程都會如此。 閱讀內容永遠不會收到任何東西。 為什么? 這兩個過程都經過測試,可以分別正常工作。 如果我不閱讀(但后來我無法處理B輸出),則整個sh也可以正常工作(不要阻塞)。

有人可以向我解釋我所理解的錯誤嗎? 對不起,我的英語近似。 如果您有一個干凈的解決方案,我也會對此感到感興趣(但是,它更願意理解為什么這個解決方案不起作用)。

// edit這是主要的(過程A):

//managing some arguments threatment, constructing object...


   pthread_t thread;//creation of the thread supposed to read

  if(pthread_create(&thread, NULL,IsKhacToolKit::threadRead, solver) != 0) {
    fprintf(stderr,"\nSomething went wrong while creating Reader thread\n" );
  }
  solver->generateDimacFile();//printing to stdout


  pthread_exit(0);
}

該線程執行的功能僅應讀取stdin並將所觀察到的字符串打印到stderr中(目前)。 目前,stderr中沒有任何內容。

generateDimacFile將一個char *打印到processB使用的stdout(最后是flush(stdout))中。 過程B就是這樣的過程: http : //www.labri.fr/perso/lsimon/glucose/

這是線程現在執行的功能:

char* satResult=(char*)malloc(sizeof(char)* solutionSize);
for (int i=0; i<2; i++){
read(0, satResult, solutionSize );
fprintf(stderr, "\n%s\n", satResult);
}
DEBUGFLAG("Getting result from glucose");

好了,現在感謝Maxim Egorushkin,我發現第一個read dont塊,但是下一個使用該bash的塊代替了:

./processA <fifo | stdbuf -o0 ./processB >fifo

如果我用那個:

stdbuf -o0 ./processA <fifo | stdbuf -o0 ./processB >fifo

在大多數情況下,我可以閱讀兩次Whoutout阻止(有時會阻止)。 我仍然看不懂3次。 我不明白為什么它會改變任何東西,因為我在generateDimacFile中刷新了stdout。

查看它在stderr中不阻塞(讀取兩次)時實際打印的內容:

c
c This is glucose 4.0 --  based on MiniSAT (Many thanks to MiniSAT team)
c



c This is glucose 4.0 --  based on MiniSAT (Many thanks to MiniSAT team)
c

c Reading from standard input... Use '--help' for help.
s to MiniSAT team)
c

相應的預期結果:

c
c This is glucose 4.0 --  based on MiniSAT (Many thanks to MiniSAT team)
c
c Reading from standard input... Use '--help' for help.
c |                                                                                                       |
s UNSATISFIABLE

您可能會阻止比賽條件。 如果processB在產生任何數據之前需要讀取大量數據,則有可能在processA產生足夠的數據之前將其餓死。 一旦發生這種情況,就會陷入僵局。 或者,如果processA在讀取某些內容之前從未生成任何數據,則兩個進程都將坐在那兒。 這實際上取決於processA和processB在做什么。

如果過程足夠簡單,那么您正在執行的操作就可以了。 例如:

$ cat a.sh
#!/bin/sh 

echo "$$"

while read line; do echo $(($line + 1 )); echo $$ read: $line >&2; sleep 1; done
$ ./a.sh < fifo | ./a.sh > fifo
26385 read: 26384
26384 read: 26385
26385 read: 26386
26384 read: 26385
26385 read: 26386
26384 read: 26387
26385 read: 26388
26384 read: 26387
^C

使用| bash or >會使進程成為塊緩沖,因此在緩沖區已滿或調用fflush之前,它不會輸出任何內容。

嘗試使用stdbuf -o0 ./processA <fifo | stdbuf -o0 processB >fifo禁用所有緩沖stdbuf -o0 ./processA <fifo | stdbuf -o0 processB >fifo stdbuf -o0 ./processA <fifo | stdbuf -o0 processB >fifo


stderr不會在您的命令行中重定向,我不確定為什么要寫入它。 寫入stdout

另一個問題是

read(0, satResult, solutionSize);
fprintf(stderr, "\n%s\n", satResult);

不正確, satResult不以零結尾,並且不處理錯誤。 修復程序

ssize_t r = read(0, satResult, solutionSize);
if(r > 0)
    fwrite(satResult, r, 1, stdout);
else
    // Handle read error.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM