mercredi 12 août 2020

Get Native Thread Handle from C++11 Thread for Win32 API [duplicate]

I want to use some Win32 API functions from windows.h on a std::thread. To start things off, I am creating and starting a std::thread. Then I want to use a Win32 API function on it by getting the handle with native_handle().

// suspend_thread.cpp

#include <windows.h>
#include <iostream>
#include <thread>

void foo()
{
    unsigned int counter = 1;
    while (counter <= 5)
    {
        // do some work and finish after about 5 seconds
        std::cout << "Running... " << counter << "/5" << std::endl;
        counter++;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Done!" << std::endl;
}

int main(void)
{
    std::cout << "Starting thread..." << std::endl;
    std::thread my_thread(foo);

    std::cout << "Waiting 3 seconds..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));

    DWORD result = SuspendThread((void*) my_thread.native_handle());
    if (result != -1) std::cout << "Successfully suspended thread!" << std::endl;
    else std::cout << "Failed to suspend thread! Error: " << GetLastError() << std::endl;

    my_thread.join();
    return 0;
}

If I don't cast the result of native_handle() to void* ...

DWORD result = SuspendThread(my_thread.native_handle());

... the code doesn't compile, because SuspendThread() expects a pointer.

.\suspend_thread.cpp:25:57: error: invalid conversion from 'std::thread::native_handle_type' {aka 'unsigned int'} to 'HANDLE' {aka 'void*'} [-fpermissive]

Now if I compile and run the first example, I get the following result.

PS> g++ -std=c++11 -pthread suspend_thread.cpp -o suspend_thread.exe
PS> ./suspend_thread.exe
Starting thread...
Waiting 3 seconds...
Running... 1/5
Running... 2/5
Running... 3/5
Failed to suspend thread! Error: 6
Running... 4/5
Running... 5/5
Done!

I tried to suspend the thread while it was running, however the function fails with the error code 6, which according to the documentation stands for ...

ERROR_INVALID_HANDLE (0x6): The handle is invalid.

... so apparently this is not the right way to pass a handle to a Win32 API function.

I know that I can pause and resume threads in another way without using the Win32 API.

Aucun commentaire:

Enregistrer un commentaire