Информация об изменениях

Сообщение 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, а это нужно в этом случае знать.

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, а это нужно в этом случае знать.

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);
        }
    }
}