Сообщение Re: Как обойти дедлок в ntdll? от 04.02.2020 7:32
Изменено 04.02.2020 7:35 RedApe
Re: Как обойти дедлок в ntdll?
Здравствуйте, Basil2, Вы писали:
B>Может есть более удачные решения?
Если я правильно понял, что происходит, и если позволяет устройство библиотеки, то можно делать так:
останавливать поток 2 не через SuspendThread, а через внутреннюю проверку, выполняемую в потоке 2. Т.е. там время от времени проверяется состояние некой переменной, и если она равна установлена то производится остановка. Первый поток должен после отдачи команды на остановку проверять, остановлен ли поток 2 на самом деле.
Судя по использованию SyspendThread, ты ничего не знаешь про std::mutext, std::lock_guard и std::conditional_variable, а это нужно в этом случае знать.
B>Может есть более удачные решения?
Если я правильно понял, что происходит, и если позволяет устройство библиотеки, то можно делать так:
останавливать поток 2 не через SuspendThread, а через внутреннюю проверку, выполняемую в потоке 2. Т.е. там время от времени проверяется состояние некой переменной, и если она равна установлена то производится остановка. Первый поток должен после отдачи команды на остановку проверять, остановлен ли поток 2 на самом деле.
Судя по использованию SyspendThread, ты ничего не знаешь про std::mutext, std::lock_guard и std::conditional_variable, а это нужно в этом случае знать.
std::mutex mutex;
// команда остановить поток
bool stop_thread;
std::conditional_variable suspend;
// поток действительно остановлен
bool thread_is_stopped;
std::conditional_variable resume;
// поток 1.
{ // останавливаем поток 2
std::lock_guard lock(mutex);
stop_thread = true;
// ожидаем сообщения об остановке потока 2
while(!thread_is_stopeed)
suspend.wait(lock);
}
// ...
// здесь поток 2 гарантированно остановлен
// делаем всё что нужно
// ...
{ // запускаем поток 2
std::lock_guard lock(mutex);
stop_thread = false;
resume.notify_one();
}
// поток 2.
while(true) // какой-то цикл обработки сообщений
{
// проверяем нет ли команды на остановку
{
std::lock_gruard lock(mutex);
if (stop_thread)
{
// сообщаем, что поток остановлен
thread_is_stopped = true;
suspend.notify_one();
// ожидаем команды на запуск
while(stop_thread)
resume.wait(lock);
}
}
}
Re: Как обойти дедлок в ntdll?
Здравствуйте, Basil2, Вы писали:
B>Может есть более удачные решения?
Если я правильно понял, что происходит, и если позволяет устройство библиотеки, то можно делать так:
останавливать поток 2 не через SuspendThread, а через внутреннюю проверку, выполняемую в потоке 2. Т.е. там время от времени проверяется состояние некой переменной, и если она установлена, то производится остановка. Первый поток должен после отдачи команды на остановку (установки переменной) проверять, остановлен ли поток 2 на самом деле.
Судя по использованию SyspendThread, ты ничего не знаешь про std::mutext, std::lock_guard и std::conditional_variable, а это нужно в этом случае знать.
B>Может есть более удачные решения?
Если я правильно понял, что происходит, и если позволяет устройство библиотеки, то можно делать так:
останавливать поток 2 не через SuspendThread, а через внутреннюю проверку, выполняемую в потоке 2. Т.е. там время от времени проверяется состояние некой переменной, и если она установлена, то производится остановка. Первый поток должен после отдачи команды на остановку (установки переменной) проверять, остановлен ли поток 2 на самом деле.
Судя по использованию SyspendThread, ты ничего не знаешь про std::mutext, std::lock_guard и std::conditional_variable, а это нужно в этом случае знать.
std::mutex mutex;
// команда остановить поток
bool stop_thread;
std::conditional_variable suspend;
// поток действительно остановлен
bool thread_is_stopped;
std::conditional_variable resume;
// поток 1.
{ // останавливаем поток 2
std::lock_guard lock(mutex);
stop_thread = true;
// ожидаем сообщения об остановке потока 2
while(!thread_is_stopeed)
suspend.wait(lock);
}
// ...
// здесь поток 2 гарантированно остановлен
// делаем всё что нужно
// ...
{ // запускаем поток 2
std::lock_guard lock(mutex);
stop_thread = false;
resume.notify_one();
}
// поток 2.
while(true) // какой-то цикл обработки сообщений
{
// проверяем нет ли команды на остановку
{
std::lock_gruard lock(mutex);
if (stop_thread)
{
// сообщаем, что поток остановлен
thread_is_stopped = true;
suspend.notify_one();
// ожидаем команды на запуск
while(stop_thread)
resume.wait(lock);
}
}
}