У меня есть простое приложение на C ++, которое должно читать строки из именованного канала POSIX:
#include<iostream>
#include<string>
#include<fstream>
int main() {
std::ifstream pipe;
pipe.open("in");
std::string line;
while (true) {
std::getline(pipe, line);
if (pipe.eof()) {
break;
}
std::cout << line << std::endl;
}
}
Шаги:
Я создаю именованный канал: mkfifo in
.
Я компилирую и запускаю код C ++, используя g++ -std=c++11 test.cpp && ./a.out
.
Я передаю данные в in
трубу:
sleep infinity > in & # keep pipe open, avoid EOF
echo hey > in
echo cats > in
echo foo > in
kill %1 # this closes the pipe, C++ app stops on EOF
При выполнении этого в Linux приложение успешно отображает вывод после каждой команды echo
, как и ожидалось (g ++ 8.2.1).
При попытке всего этого процесса в macOS вывод отображается только после закрытия канала (т.е. после kill %1
).
Я начал подозревать какую-то проблему с буферизацией, поэтому я попытался отключить ее следующим образом:
std::ifstream pipe;
pipe.rdbuf()->pubsetbuf(0, 0);
pipe.open("out");
С этим изменением приложение ничего не выводит после первого echo
, затем печатает первое сообщение после второго echo
(«эй») и продолжает делать это, всегда отставая от сообщения и отображая сообщение предыдущего echo
вместо выполненного.
Последнее сообщение отображается только после закрытия канала.
Я обнаружил, что на macOS g++
в основном clang++
, а
g++ --version
возвращает: «Apple LLVM версии 10.0.1 (clang-1001.0.46.3)».
После установки реального g ++ с использованием Homebrew программа-пример работает, как и в Linux.
Я строю простую библиотеку IPC, построенную на именованных каналах по разным причинам, поэтому на данный момент это правильное функционирование - довольно большое требование для меня.
Что вызывает это странное поведение при использовании LLVM? (обновление: это вызвано libc ++)
Это ошибка?
Каким-то образом гарантируется, как это работает на g ++ стандартом C ++?
Как я могу заставить этот фрагмент кода работать правильно, используя clang++
?
Обновление:
Кажется, это вызвано реализацией libc ++ getline()
.
Ссылки по теме:
Хотя вопросы все еще стоят.