1

在我的多线程应用程序中,我使用了 sleep() 函数(来自 GLFW 库的函数):

glfwSleep(..);

它显然导致我的应用程序出现段错误,因为我的调用堆栈显示:

#0 76CFC2BC WaitForSingleObjectEx() (C:\Windows\system32\kernel32.dll:??)
#1 00000016 ??() (??:??)
#2 0000006C ??() (??:??)
#3 00000000 ??() (??:??)

glfwSleep()用于线程内部。那很危险吗?为什么我的程序会因此而出现段错误?

编辑:

当 的参数glfwSleep()< 0.02 (secs) 时,它不会出现段错误!

编辑2:

来自 GLFW 的官方文档:

在您习惯之前编写线程应用程序可能会非常尴尬,但有一些非常容易遵循的关键规则:

  • 始终确保对线程之间共享的数据的独占访问!
  • 确保线程正确同步!
  • 从不忙等待!

我想我得到了答案..现在必须找到替代方案..

谢谢!

4

3 回答 3

2

来自GLFW 维基

GLFW 不适用于 GHC 线程、forkIO 或 threadDelay。因此,如果可以,请避免使用它们。

于 2009-05-23T23:22:20.557 回答
1

段错误的线程是否与 glfwSleep() 的调用者线程相同?

似乎是调用 WaitForMultipleObjectsEx API 引起的崩溃。您是否指定并将正确的同步对象和数字传递给 WaitForMultipleObjectsEx?

于 2009-05-23T23:28:22.823 回答
1

引用The Pragmatic Programmer 的话,

``select'' 没有坏掉

在操作系统或编译器中,甚至在第三方产品或库中都很少发现错误。该错误最有可能在应用程序中。

为什么你的程序在调用WaitForSingleObjectEx()glfwSleep()调用Sleep()?好吧,即使您没有 的源代码Sleep(),它也不完全是一个黑匣子。反汇编Sleep(),您可能会看到(取决于您拥有的 Windows 版本)Sleep()调用或 tail-calls SleepEx()。在 XP 上SleepEx()调用NtDelayExecutionThread(),而在 Vista 上调用WaitForSingleObjectEx().

那么你的堆栈的其余部分发生了什么?00000016、0000006C 和 00000000 不是有效的返回地址。如果在您的代码中的某个地方,您将指向堆栈分配缓冲区的指针传递给另一个线程,并且当您的程序处于睡眠状态时,另一个线程破坏了第一个线程的堆栈,我不会感到惊讶。步入Sleep(),在返回地址上设置内存断点,或许就能抓到罪魁祸首。

于 2009-05-24T16:57:02.337 回答