gpt4 book ai didi

c++ - 使用 SDL2 从 C++11 线程可移植地退出 readline

转载 作者:太空宇宙 更新时间:2023-11-04 12:41:26 24 4
gpt4 key购买 nike

考虑一个简单的程序:(使用带 pthread 的 g++ 编译时需要 -std=c++11 -lpthread -lreadline -lSDL2)

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

主线程用SDL2创建一个窗口window,进入一个SDL事件循环,同时线程console使用readline重复从控制台读取>。当窗口退出时,它会等待控制台线程完成然后退出。

程序运行良好;但是,如何让控制台线程在窗口退出时停止?

如果程序只使用单线程就好了。如果退出控制台 readline 也可以退出程序。


Exit readline is easy ,但那里的所有答案都存在问题 - pthread_killreset -Q 不可移植。

Terminating a thread is easy (使用 std::terminate.detach()),但控制台处于错误状态,因为 readline 没有正常终止.要重置控制台,可以使用 reset -Q,但这不可移植。

使用 readline 的替代(异步)接口(interface)不起作用,因为 SDL 不监听控制台上的事件。使用 select 也是不可移植的。

最佳答案

实际上,readline并不是完全阻塞的,它每1/10秒调用一次rl_event_hook(默认)。可以检查程序是否在事件 Hook 内停止,如果是,则执行 longjmpthrow 以退出函数(在本例中为 int 被使用,尽管可以定义你自己的异常类):

std::atomic<bool> stopped (false);

rl_event_hook = [](){
if (stopped)
throw 0;
return 0;
};

try {
/* something calls readline() */
} catch (int) {
rl_cleanup_after_signal();
}
return 0;

或通过设置 rl_done = 1:(当 rl_event_hooknullptr 时,这将不起作用。还要注意 rl_event_hook 在按住键时不被调用,有必要覆盖 rl_getc_function 来改变行为。它是 not recommended 从另一个线程修改 rl_done )

std::atomic<bool> stopped (false);

rl_event_hook = [](){
if (stopped)
rl_done = true;
return 0;
};

/* something calls readline() */
if (stopped) return 0;
/* process */
return 0;

在主线程中使用:

stopped = true;
console.join();

关于c++ - 使用 SDL2 从 C++11 线程可移植地退出 readline,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54086407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com