Fifoという名前のパイプ[閉じる]

Fifoという名前のパイプ[閉じる]

私はcppの2つのプロセス間でデータを書き込んで読み込む名前付きパイプを実装しています。最初のプロセスは画像からリアルタイムで特徴点を取得し、2番目のプロセスは特徴点を読み込みます。うまく動作しますが、2つのプロセス間で数回のデータ交換後にTalkerコードが停止します。パイプからデータを読み取るにはパイプを閉じる必要があることがわかり、whileループの外側の話者コードでファイル記述子を閉じようとすると、リスナーファイルは変数の新しい値にアクセスできません。 。今は解決策が見つかりません。私は何を見逃していますか?

以下は、fifoファイルに変数を書き込む関数のMCVEです。

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>

/*Function Prototypes*/
void(cv::Mat frame);    
int(talker);

 int talker(float depthright)
 {
   int fd;
   char depthstring[1024];    
   sprintf(depthstring, "%4.4f", depthright);

   char * myfifo = "/tmp/myfifo";

   mkfifo(myfifo, 0666);           /* create the FIFO (named pipe) */
   fd = open(myfifo, O_WRONLY/* | O_NONBLOCK*/);       
   write(fd, depthstring, sizeof(depthright) );    

   /* close FIFO and delete fifo names from file system */
   close(fd);
   unlink(myfifo); 

   return 0;
}

int main( int argc, char* argv[] )
{
 cv::Mat frame;
//convert frame to grayscale, equalize histogram of grayed frame
//detect faces and then detect eyes; acquire eye depth values as depthright
 talker(depthright);     //call fifo talker funtion
return 0;
 }

リスナーは次のとおりです。

int main()
 {    
  int fd;
  char * myfifo = "/tmp/myfifo";
  char buf[1024];

    while(1)
    {
        //READ actual depth fifo
        fd = open(myfifo, O_RDONLY | O_NONBLOCK);
        read(fd, buf, MAX_BUF);
        float depth = strtof(buf, NULL);
        printf("\ndepth actual: %4.2f", depth);              
    }    

     //Close read buffers
     close(fd);

     return 0;
  }

答え1

あなたはバイトを送信しており、実際のサイズではなく部分sizeof(float)文字列にすぎません。depthstringstrlen(depthstring)+1sizeof(float)

あなたができることの1つは、文字列への変換を削除することです。名前付きFIFOを読み取る両方のプロセスが同じシステム上にあるため(いいえ、FIFOはNFSでは機能しません)、aが両方のプロセスfloatで同じように表現されると仮定できます。だから:

int talker(float depthright)
 {
   int fd;
   const char * myfifo = "/tmp/myfifo";

   mkfifo(myfifo, 0666);           /* create the FIFO (named pipe) */
   fd = open(myfifo, O_WRONLY/* | O_NONBLOCK*/);
   write(fd, &depthright, sizeof(depthright) );    

   /* close FIFO and delete fifo names from file system */
   close(fd);
   /* Don't delete the FIFO yet. The reader may not have opened
    * it yet.
    */

   return 0;
}

それから:

int main()
 {    
  int fd;
  const char * myfifo = "/tmp/myfifo";

    while(1)
    {
        //READ actual depth fifo
        fd = open(myfifo, O_RDONLY | O_NONBLOCK);
        float depth;
        read(fd, &depth, sizeof(depth));
        // Close read buffers now, since we open it with
        // each iteration. Waiting until after the loop
        // will result in only the last fd being closed.

        // Furthermore, there's a tight limit on how many
        // FDs you can have open at once.
        close(fd);    
        printf("\ndepth actual: %4.2f", depth);
        // Without this, libc may hold the output in a buffer
        // until the next float is read.
        fflush(stdout);
    }    
     /* NOT REACHED. The compiler may actually delete this code, since
      *  it can prove that this part will never be executed.
      */ 
     unlink(myfifo); 
     return 0;
  }

答え2

問題の小さな部分は、ループopen内で作業を実行していることですwhile (1) … read(ループ内で生成されたファイル記述子を閉じずに)。あなたのコードは、FIFOのために何百ものファイル記述子を蓄積すると予想されます。通常、1,000個に達すると、openオープンファイル(EMFILE)が多すぎてシステムが失敗し始めます。

関連情報