Тестовая программа StdoutWriter записывает некоторый текст ( {"id": 0, "cmd": 1} ) в стандартный вывод в течение 1 секунды, а затем снова через 5 секунд, а затем ждет 10 секунд и выходит. Я запустил эту программу сам и проверил правильность времени и результатов.
Другая тестовая программа StdinReader (код приведен ниже), использующий в будущем чтение stdin и печать каждой строки. StdinReader не работает должным образом.
Я запускаю две программы с терминала с помощью:
./StdoutWriter | ./StdinReader
Проблема, которую я вижу, заключается в том, что чтение каждой строки кажется, блокирует, пока StdoutWriter выходит.
Наблюдаемый неправильный вывод выглядит следующим образом:
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
you wrote {"id":0,"cmd":1}
waiting...
you wrote
waiting...
you wrote
waiting...
you wrote
Правильный вывод должен выглядеть следующим образом:
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
waiting...
waiting...
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
waiting...
waiting...
waiting...
you wrote
waiting...
you wrote
waiting...
you wrote
Вот код для StdinReader, который я получил: https://gist.github.com/vmrob/ff20420a20c59b5a98a1
#include <iostream>
#include <chrono>
#include <future>
#include <string>
std::string GetLineFromCin() {
std::string line;
std::getline(std::cin, line);
return line;
}
int main() {
auto future = std::async(std::launch::async, GetLineFromCin);
while (true) {
if (future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto line = future.get();
// Set a new line. Subtle race condition between the previous line
// and this. Some lines could be missed. To aleviate, you need an
// io-only thread. I'll give an example of that as well.
future = std::async(std::launch::async, GetLineFromCin);
std::cout << "you wrote " << line << std::endl;
}
std::cout << "waiting..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}