При использовании FIFO в одном процессе, похоже, что после того, как оба конца были открыты, а затем закрыты, повторное использование FIFO невозможно. Любая попытка открыть закрытый конец завершается неудачей или дескриптор возвращенного файла бесполезен.Невозможно повторно открыть FIFO, когда тот же процесс использует оба конца FIFO
Возможно ли обойти это поведение, или мы должны держать оба конца FIFO открытым до тех пор, пока мы не будем абсолютно уверены, что нам это больше не нужно?
Вот некоторые тестового кода, который показывает и попытка возобновить закрытый конец записи в виде FIFO:
#include <iostream>
#include <cstdio>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
using namespace std;
int main(int argc, const char **argv)
{
cout << "Creating an instance of a named pipe..." << endl;
mode_t prevMask = umask(0);
if (mknod("my_pipe", S_IFIFO | 0666, 0))
return -1;
umask(prevMask);
cout << "Opening Read end..." << endl;
int fdM = open("my_pipe", O_RDONLY | O_NONBLOCK);
if (fdM == -1)
return -1;
cout << "Opening Write end..." << endl;
int fdS = open("my_pipe", O_WRONLY | O_NONBLOCK);
if (fdS == -1)
return -1;
cout << "Sending data to pipe..." << endl;
const char *data = "Hello my friend!";
ssize_t NbOfBytesWritten = write(fdS, data, strlen(data));
if (NbOfBytesWritten < 0)
return -1;
cout << "Number of bytes sent: " << NbOfBytesWritten << endl;
cout << "Closing Write end..." << endl;
if (close(fdS))
return -1;
cout << "Reopening Write end..." << endl;
fdS = open("my_pipe", O_WRONLY | O_NONBLOCK);
if (fdS == -1)
{
cout << "open() - failed("<< errno << "): " << strerror(errno) << '.';
remove("my_pipe");
return -1;
}
cout << "Sending some more data to pipe..." << endl;
data = "What's up?";
NbOfBytesWritten = write(fdS, data, strlen(data));
if (NbOfBytesWritten < 0)
return -1;
cout << "Number of bytes sent: " << NbOfBytesWritten << endl;
cout << "Reading data from pipe..." << endl;
char buff[128];
ssize_t numBytesRead = read(fdM, buff, 127);
if (NbOfBytesWritten < 0)
return -1;
buff[numBytesRead] = '\0'; // null terminate the string
cout << "Number of bytes read: " << numBytesRead << endl;
cout << "Message: " << buff << endl;
cout << "Closing Write end..." << endl;
if (close(fdS))
return -1;
cout << "Closing Read end..." << endl;
if (close(fdM))
return -1;
cout << "Deleting pipe..." << endl;
if (remove("my_pipe"))
return -1;
return 0;
}
Здесь выход:
Creating an instance of a named pipe...
Opening Read end...
Opening Write end...
Sending data to pipe...
Number of bytes sent: 16
Closing Write end...
Reopening Write end...
open() - failed(6): No such device or address.
Я также испытал подобный код пытается возобновить закрытый конец чтения (в то время как конец записи был открыт). В этом случае функция open() будет успешной, но функция read(), использующая дескриптор файла, возвращенный функцией open(), завершится с ошибкой: Ошибка связи при отправке. (70)
EDIT:
Я использую CYGWIN.
Это работает без ошибок на моем Linux. – PSkocik
Вам нужно, чтобы оба конца были открыты. Когда все концы записи закрыты, читатель получает EOF. И когда все прочитанные концы закрыты, писатель получает «EPIPE», если они пытаются писать. – Barmar
@Barmar - Вопрос в том, что «Почему невозможно возобновить конец FIFO?» Речь идет не о том, как писать или читать с FIFO, который не связан с обоих концов. – Guett31