Named Pipes linux

I made 2 threads, you need to read another to write. But I get undefined behavior, sometimes I can read 1 line, sometimes 1000. This does not make much sense to me.

I do the following: 1. I create fifo with mkfifo () in main.cpp 2. I start 2 threads, one of which reads, the other writes. reader.cpp, writer.cpp

In these threads, every cycle I open fifo, and I close it because it does not work if I do it only outside of the cycle, which I find also strange.

I was looking for good examples, but not found.

My questions are simple, how can I make fifo (Reader) wait for incoming data and read it when it is available. It should be able to work with a frequency of 4 MHz.

I hope someone can help me, because on the third day I rack my brains over this. If it matters im, using Qt 4.8.

EDIT: I found a solution to my problem:

main.cpp

#include <QtCore/QCoreApplication> #include "reader.h" #include "writer.h" #include <sys/types.h> // mkfifo #include <sys/stat.h> // mkfifo #include <fcntl.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int fifo = mkfifo("/tmp/fifo", S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); Reader r; Writer w; r.start(); w.start(); return a.exec(); } 

writer.h

 #ifndef WRITER_H #define WRITER_H #include <QThread> #include <stdio.h> #include <iostream> #include <errno.h> #include <string.h> #include <fcntl.h> class Writer : public QThread { Q_OBJECT public: explicit Writer(QObject *parent = 0); private: void run(); }; #endif // WRITER_H 

reader.h

 #ifndef READER_H #define READER_H #include <QThread> #include <stdio.h> #include <iostream> #include <errno.h> #include <string.h> #include <fcntl.h> class Reader : public QThread { Q_OBJECT public: explicit Reader(QObject *parent = 0); private: void run(); }; #endif // READER_H 

writer.cpp

 #include "writer.h" char * phrase = "Stuff this in your pipe and smoke it\n"; using namespace std; Writer::Writer(QObject *parent) : QThread(parent) {} void Writer::run() { int num, fifo; if ((fifo = open("/tmp/fifo", O_WRONLY)) < 0) { printf("%s\n", strerror(errno)); return; } while (true) { if ((num= write(fifo, phrase, strlen(phrase)+1)) < 0) { printf("ERROR: %s\n", strerror(errno)); } } close(fifo); } 

reader.cpp

 #include "reader.h" using namespace std; Reader::Reader(QObject *parent) : QThread(parent) {} void Reader::run() { int num, fifo; char temp[38]; if ((fifo = open("/tmp/fifo", O_RDONLY)) < 0) { printf("%s\n", strerror(errno)); return; } while (true) { if ((num = read(fifo, temp, sizeof(temp))) < 0) { printf("%s\n", strerror(errno)); } printf("In FIFO is %d %s \n", num, temp); } close(fifo); } 
+6
source share
2 answers

The main functions read () and write () do not promise to read or write all available data.

You need something like:

 int tot = 0; while (tot < sizeof(temp)) { num = read(fifo, temp + tot, sizeof(temp) - tot); if (num < 0) break; tot += num; } 

And the same thing for the record.

+3
source

I met the same problem when I periodically opened and closed one channel. Reforming the pipe (during reading, when EOF is running) will be the solution.

+1
source

Source: https://habr.com/ru/post/926204/


All Articles