Рассмотрим простую программу: (требуется -std=c++11 -lpthread -lreadline -lSDL2
при компиляции с g ++ с помощью pthread)
#include <iostream>
#include <thread>
#include <SDL2/SDL.h>
#include <cstdlib>
extern "C" {
#include <readline/readline.h>
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
auto window = SDL_CreateWindow("title", 0, 0, 200, 200, SDL_WINDOW_SHOWN);
std::thread console([](){
while (true) {
char *console_input_c_str = readline("> ");
if (console_input_c_str == NULL)
break;
std::cout << "line: " << console_input_c_str << '\n';
std::free(console_input_c_str);
}
});
while (true) {
SDL_Event event;
SDL_WaitEvent(&event);
std::cerr << "received event type "<<event.type<<'\n';
if(event.type == SDL_WINDOWEVENT &&
event.window.event == SDL_WINDOWEVENT_CLOSE)
break;
}
SDL_DestroyWindow(window);
SDL_Quit();
console.join();
}
Основной поток создает окно window
с SDL2, вводит цикл событий SDL, в то время как поток console
повторно считывает данные с консоли, используя readline
. Когда окно закрывается, оно ожидает завершения потока консоли и затем завершается.
Программа отлично работает; однако как я могу заставить консольный поток останавливаться при выходе из окна?
Хорошо, если программа использует только один поток. Также хорошо, если выход из консоли readline завершает работу программы.
Выйти из readline легко , но там есть проблема со всеми ответами - pthread_kill
или reset -Q
не является переносимым.
Завершение потока легко (с использованием std::terminate
или .detach()
), но консоль остается в плохом состоянии, потому что readline
не завершается нормально. Для сброса консоли можно использовать reset -Q
, но это не переносимо.
Использование альтернативного (асинхронного) интерфейса readline не работает, поскольку SDL не прослушивает события на консоли. Использование select
также не переносимо.