杀死 SDL 2 线程 (C)

Killing SDL 2 threads (C)

SDL 2 具有创建和管理线程的良好功能,并且是跨平台的。 SDL 1 具有终止这些线程的功能,但 SDL 2 不再具有此功能,正如他们在其 wiki 上提到的那样。

我曾经使用 OS 本机函数(Windows 线程和 Linux pthread)编写线程程序,我可以做到这一点。

我知道你应该对你的线程进行编程,这样你就永远不必杀死它们,而且我相当擅长编写线程,但现在我正在做一个项目,允许用户编写我将要编写的脚本代码运行 来自线程内部,因此它们可以 运行 并行。

如果这些脚本 运行 超过 10 秒,则认为它们已挂起。如果用户想要退出应用程序并且线程很忙,他们将不得不等待这些线程完成,如果脚本不好,可能永远不会结束。

在那种情况下,我认为杀死线程是 only/best 选项,通知用户脚本有问题。

为什么 SDL 2 不再支持此功能,有解决办法吗?

当然,首先想到的应该是:真的有必要吗。不能添加要求线程正确退出并清理的信号吗?

线程应始终具有自行停止或监视 quit-requests.

的机制

但是当你的项目拥有所有这些但允许用户为这些线程编写他们自己的代码时,例如通过 Lua 脚本,你总是会让人通过添加无限循环(可能是不是故意的)。在这种情况下,在空闲时间监视事件将无济于事,因为不会有空闲时间。

所以在我看来,SDL 没有线程终止功能是一个错误的决定。这就像说汽车不应该有安全气囊一样,因为人们希望用户采取预防措施,不要撞到东西上。与此同时,即使被告知不要撞车,司机还是挽救了很多生命。

我见过的最佳答案是以依赖于平台的方式自己完成。 SDL 提供了一种获取线程 ID 的方法:SDL_GetThreadID。此 ID 与 OS 赋予线程的 ID 相同,然后可用于通过特定于平台的函数终止线程:

#ifdef _WIN32
TerminateThread(SDL_GetThreadID(t), 0);
#end
#ifdef __linux
pthread_kill(SDL_GetThreadID(t), 0);
#endif

我不知道 SDL 支持的其他平台,所以你当然也应该确保研究他们的方式。我想 SDL 也使用 Mac OS 的 pthread 实现,所以它也可能在那里工作。我以前写自己的线程代码的时候就是这样。

我正在研究建议的线程中断。如果这证明有帮助,我也会post在这里。

另一种可能的解决方案当然是可以要求使外部代码成为可能的代码停止执行。我不认为 Lua 提供这样的东西,但如果我找到它,我肯定会喜欢它。

编辑:对于Lua,可以设置触发每N条指令的调试钩子。这样,应该可以在 quit-request 执行外部代码时检查 quit-request 。我一定会研究这个(主要是检查性能),这样杀死线程肯定会成为最后的手段。参见 lua_sethook