我有这个程序.cpp:
#include <stdio.h>
#include <windows.h>
DWORD WINAPI separateThread(LPVOID)
{ printf("thread waiting user input\n");
char str[128]; fgets(str, 128, stdin);
printf("fgets END ...");
}
int main()
{
printf("program start autokill after 5sec\n");
DWORD tid; HANDLE tha =CreateThread(0,0, separateThread, 0,0,&tid);
Sleep(5000);
// XXXXXXXX what to put here to Kill fgets-callin-thread ???????????
}
在 Linux 中编译:
i686-w64-mingw32-gcc program.cpp
并运行它:
wine a.exe
...我希望它能够自行结束,无需任何用户输入。但总是有 err:ntdll:RtlpWaitForCriticalSection 女巫阻止一切。
我应该在 XXXXX 地方放什么?
没有帮助的解决方案: TerminateThread(tha, 0)、ExitProcess(0)、reopen(stdin)、fclose(stdin) ... 通过 kbhit-getch 组合实现自己的 'my_gets' 函数对于 xp、win7 和 win8 目标来说是一个很好的解决方案,但在 WINE 中使用 kbhit不起作用。
最佳答案
终止线程几乎永远都不安全。它可能会使事情处于不一致、损坏的状态。
例如,考虑一个已完成内存分配的线程。线程锁定了用于同步堆访问的互斥体。如果突然终止,线程将不会释放锁。任何后续分配内存的尝试都将挂起。
一种可能的解决方案是终止整个进程(terminateprocess 函数)。这将导致所有线程被终止并且进程退出而不执行任何清理。例如,这意味着 stdout 不会被刷新,注册的 atexit 处理程序将不会像任何 C++ 析构函数一样运行。但是,操作系统级资源(例如打开的文件和内存)将被正确释放。
还有 exitprocess 来执行有序的进程关闭。它执行清理,但由于线程突然终止而导致全局状态损坏(考虑在清理期间调用 free(),如果堆损坏,它会挂起)。
旁注。使用_beginthread instead of CreateThread为了在新线程中正确初始化c运行时库。
关于c - 杀死 mingw 和 wine 中的 fgets 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28119770/