Search code examples
c++multithreadingwinapistdthread

How to handle a PostMessageThread message in std::thread?


Somewhere in my main thread I am calling PostThreadMessage(). But I don't know how to handle it in the std::thread I have sent it to.

I am trying to handle it in std::thread like this:

while(true) {
    if(GetMessage(&msg, NULL, 0, 0)) {
        // Doing appropriate stuff after receiving the message.
    }
}

And I am sending the message from the main thread like this:

PostThreadMessage(thread.native_handle(), WM_CUSTOM_MESSAGE, 0, 0);

I don't know if I am supposed to receive the message as I did in my thread.

All I want to know is, how to check whether the "worker thread" is receiving the message I am sending it.


Solution

  • What std::thread::native_handle() returns is implementation-defined (per [thread.req.native] in the C++ standard). There is no guarantee that it even returns a thread ID that PostThreadMessage() wants.

    For instance, MSVC's implementation of std::thread uses CreateThread() internally, where native_handle() returns a Win32 HANDLE. You would have to use GetThreadId() to get the thread ID from that handle.

    Other implementations of std::thread might not use CreateThread() at all. For instance, they could use the pthreads library instead, where native_handle() would return a pthread_t handle, which is not compatible with Win32 APIs.

    A safer way to approach this issue is to not use native_handle() at all. Call GetCurrentThreadId() inside of your thread function itself, saving the result to a variable that you can then use with PostThreadMessage() when needed, for example:

    struct threadInfo
    {
        DWORD id;
        std::condition_variable hasId;
    };
    
    void threadFunc(threadInfo &info)
    {
        info.id = GetCurrentThreadId();
        info.hasId.notify_one();
    
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0)) {
            // Doing appropriate stuff after receiving the message.
        }
    }
    
    ...
    
    threadInfo info;
    std::thread t(threadFunc, std::ref(info));
    info.hasId.wait();
    ...
    PostThreadMessage(info.id, WM_CUSTOM_MESSAGE, 0, 0);