Win32 не может возобновить поток, который сам приостанавливает - PullRequest
4 голосов
/ 03 января 2012

В Win32 я хочу приостановить поток с помощью Suspend(GetCurrentThread());, но обнаружил, что не могу возобновить его с помощью ResumeThread(suspend thread handle); Но я ничего не нашел.

Вот мой код.

HANDLE C;
DWORD WINAPI A (LPVOID in)
{
    C = GetCurrentThread();
    cout << "1";
    SuspendThread (C);
    cout << "4";
    return 0;
}
DWORD WINAPI B (LPVOID in)
{
    Sleep (200);
    cout << "2";
    ResumeThread (C);
    cout << "3";
    return 0;
}
int main()
{
    CreateThread (NULL, 0, A, NULL, 0, NULL);
    CreateThread (NULL, 0, B, NULL, 0, NULL);
    Sleep (INFINITE);
    return 0;
}

И все, что я получаю на экране, это 123.

1 Ответ

2 голосов
/ 03 января 2012

Сейчас возможно, что когда B вызывает ResumeThread, переменная C содержит неинициализированное значение.

Однако текущая причина, по которой ваш код не работает, заключается в том, что GetCurrentThread возвращает только дескриптор псевдопотока, значение, интерпретируемое как обозначение текущего дескриптора потока. Чтобы получить реальный, который можно использовать из других потоков, вы можете взять его по возвращению первого CreateThread вызова или преобразовать псевдо-дескриптор с помощью DuplicateHandle.

Редактировать : Используя метод 1:

HANDLE C;
DWORD WINAPI A (LPVOID in)
{
    cout << "1";
    SuspendThread (C);
    cout << "4";
    return 0;
}
DWORD WINAPI B (LPVOID in)
{
    Sleep (200);
    cout << "2";
    ResumeThread ((HANDLE)in);
    cout << "3";
    return 0;
}
int main()
{
    C = CreateThread (NULL, 0, A, NULL, 0, NULL);
    CreateThread (NULL, 0, B, (LPVOID)C, 0, NULL);
    Sleep (INFINITE);
    return 0;
}

На самом деле существует другая проблема с вашим кодом, заключающаяся в том, что дескрипторы, возвращаемые из CreateThread, игнорируются, когда они должны быть закрыты. Кроме того, отсутствует проверка ошибок, но я предположил, что вы ее пропустили для краткости.

Следует также отметить, что в зависимости от времени переключения контекста на самом деле для вышеприведенного кода возможен вывод:

1243

Используя метод 2:

HANDLE C = NULL;
DWORD WINAPI A (LPVOID in)
{
    C = GetCurrentThread();
    DuplicateHandle( GetCurrentProcess(), C, GetCurrentProcess(), &C, 0, FALSE, DUPLICATE_SAME_ACCESS );
    cout << "1";
    SuspendThread (C);
    cout << "4";
    return 0;
}
DWORD WINAPI B (LPVOID in)
{
    Sleep (200);
    cout << "2";

    while( C == NULL ) {
      Sleep(100);
    }
    ResumeThread(C);
    cout << "3";
    return 0;
}
int main()
{
    CreateThread (NULL, 0, A, NULL, 0, NULL);
    CreateThread (NULL, 0, B, NULL, 0, NULL);
    Sleep (INFINITE);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...