Как glfwSleep () может вызвать ошибку? - PullRequest
1 голос
/ 24 мая 2009

в моем многопоточном приложении я использую функцию sleep () (из библиотеки GLFW):

glfwSleep(..);

и это, очевидно, приводит мое приложение к segfaulting, как показывает мой стек вызовов:

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

glfwSleep() используется внутри потока. Это опасно? Почему в результате этого моя программа имеет сегфалтинг?

Edit:

Когда параметр glfwSleep() равен <0,02 (с), он не перестаёт работать! </p>

Редактировать 2:

Из официальной документации GLFW:

Написание потоковых приложений может быть очень неловко, прежде чем привыкнуть это, но есть несколько ключевых правил, которые довольно просто следовать:

  • ВСЕГДА обеспечивает эксклюзивный доступ к данным, которые совместно используются потоками!
  • Убедитесь, что потоки синхронизированы правильно!
  • НИКОГДА не занят, подождите!

Я думаю, что получил свой ответ .. теперь нужно найти альтернативу ..

Спасибо!

Ответы [ 3 ]

2 голосов
/ 24 мая 2009

С вики GLFW :

GLFW плохо работает с GHC потоки, forkIO или threadDelay. Так избегайте их, если можете.

1 голос
/ 24 мая 2009

Цитировать Прагматичный программист ,

`` выберите ’’ не сломано

Редко найти ошибку в ОС или компиляторе, или даже сторонний продукт или библиотека. Ошибка, скорее всего, в применение.

Почему ваша программа вызывает WaitForSingleObjectEx(), когда glfwSleep() вызывает Sleep()? Ну, хотя у вас нет исходного кода для Sleep(), это не совсем черный ящик. Разберите Sleep(), и вы, вероятно, увидите (в зависимости от того, какая у вас версия Windows), что Sleep() либо вызывает, либо выполняет хвостовые вызовы SleepEx(). В XP SleepEx() вызывает NtDelayExecutionThread(), а в Vista - WaitForSingleObjectEx().

Так что случилось с остальной частью вашего стека? 00000016, 0000006C и 00000000 не являются действительными адресами возврата. Я не удивлюсь, если где-нибудь в вашем коде вы передадите указатель на буфер, выделенный стеком, другому потоку, и пока ваша программа спит, этот другой поток разрушает стек первого потока. Войдите в Sleep(), установите точку возврата памяти на обратный адрес, и вы сможете поймать виновного.

1 голос
/ 24 мая 2009

Является ли поток segfault тем же потоком, что и вызывающий модуль glfwSleep ()?

похоже, что сбой вызван вызовом API WaitForMultipleObjectsEx. Вы указываете и передаете правильные объекты синхронизации и числа в WaitForMultipleObjectsEx?

...