저는 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)
하위 문자열일 뿐입니다 .depthstring
strlen(depthstring)+1
sizeof(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)이 너무 많아 시스템이 실패하기 시작합니다.