在我的多线程应用程序中,我正在使用sleep()函数(来自GLFW库的函数):
glfwSleep(..);
它显然引导我的应用程序进行segfaulting,因为我的调用堆栈显示:
#0 76CFC2BC WaitForSingleObjectEx() (C:\Windows\system32\kernel32.dll:??)
#1 00000016 ??() (??:??)
#2 0000006C ??() (??:??)
#3 00000000 ??() (??:??)
glfwSleep()
用于线程内部。那危险吗?为什么我的程序会因此而产生分裂?
当glfwSleep()
的参数是< 0.02(秒)它不会发生段错!
来自GLFW的官方文件:
编写线程应用程序可能是 在你习惯之前非常尴尬 它,但有一些关键规则 很容易理解:
- 始终确保对线程之间共享的数据进行独占访问!
- 确保线程正确同步!
- 永远不要等待!
我想我得到了答案......现在就找到另一种选择..
谢谢!
答案 0 :(得分:2)
GLFW与GHC不兼容 线程,forkIO或threadDelay。所以 如果可以,请避免使用它们。
答案 1 :(得分:1)
段错误的线程是否与glfwSleep()调用者的线程相同?
似乎是由WaitForMultipleObjectsEx API调用引起的崩溃。 你指定并传递给WaitForMultipleObjectsEx的正确同步对象和数字吗?答案 2 :(得分:1)
``select''没有破碎
很少见 在OS或编译器中找到错误, 甚至是第三方产品或 图书馆。这个bug最有可能出现在 应用
为什么当WaitForSingleObjectEx()
调用glfwSleep()
时,您的程序会调用Sleep()
?好吧,即使你没有Sleep()
的源代码,它也不是一个完整的黑盒子。反汇编Sleep()
您可能会看到(取决于您拥有的Windows版本)Sleep()
是否可以调用SleepEx()
。在XP上,SleepEx()
拨打NtDelayExecutionThread()
,在Vista上拨打WaitForSingleObjectEx()
。
那么堆栈的其他部分发生了什么? 00000016,0000006C和00000000无效的返回地址。如果你的代码中的某个地方,你将指向堆栈分配的缓冲区的指针传递给另一个线程,并且当你的程序正在休眠时,我不会感到惊讶,那么其他线程会破坏第一个线程的堆栈。进入Sleep()
,在返回地址上放置一个内存断点,你就可以找到罪魁祸首。