Fifo라는 이름의 파이프 [닫기]

Fifo라는 이름의 파이프 [닫기]

저는 cpp의 두 프로세스 간에 데이터를 쓰고 읽는 명명된 파이프를 구현하고 있습니다. 첫 번째 프로세스는 이미지에서 실시간으로 특징점을 획득하고, 두 번째 프로세스는 특징점을 읽어옵니다. 잘 작동하지만 두 프로세스 간에 몇 번의 데이터 교환 후에 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)

당신이 할 수 있는 한 가지는 문자열로의 변환을 제거하는 것입니다. 명명된 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)이 너무 많아 시스템이 실패하기 시작합니다.

관련 정보