Именованные трубы linux

Я сделал 2 темы, один должен прочитать другой должен написать.
Но я получаю неопределенное поведение, иногда я могу прочитать 1 строку, иногда 1000. Это не имеет большого смысла для меня.

Что я делаю, это следующее:
1. Я создаю fifo с помощью mkfifo () в main.cpp
2. Я запускаю 2 потока, один из которых читает, другой пишет. reader.cpp, writer.cpp

В этих потоках каждый цикл я открываю fifo и закрываю его, потому что он не будет работать, если я сделаю это только один раз за пределами цикла, что я нахожу также странным.

Я искал хорошие примеры, но я не нашел ни одного.

Мои вопросы просты, как я могу заставить fifo (Reader) ждать входящие данные и читать их, когда они будут доступны. Он должен быть в состоянии работать на частоте 4 МГц.

Я надеюсь, что кто-нибудь может мне помочь, потому что это третий день, когда я ломаю голову над этим. Если это важно, я использую Qt 4.8.

РЕДАКТИРОВАТЬ: я нашел решение моей проблемы:

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);
}

7

Решение

Основные функции read () и write () не обещают читать или записывать все доступные данные.

Вам нужно что-то вроде:

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

И то же самое для записи.

3

Другие решения

Я встречал ту же проблему, когда периодически открывал и закрывал одну трубу. Повторное создание канала (в процессе чтения, когда EOF встречается) будет решением.

1

По вопросам рекламы [email protected]