私は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)
文字列にすぎません。depthstring
strlen(depthstring)+1
sizeof(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)が多すぎてシステムが失敗し始めます。