Home > Blockchain >  How to pass std::thread as thread id in PostThreadMessage?
How to pass std::thread as thread id in PostThreadMessage?

Time:09-04

How could I pass the id of a std::thread thread as the id into PostThreadMessage?

Like suppose, I have a thread:

// Worker Thread

auto thread_func = [](){
    while(true) {
        MSG msg;
        if(GetMessage(&msg, NULL, 0, 0)) {
            // Do appropriate stuff depending on the message
        }
    }
};

std::thread thread_not_main = std::thread(thread_func);

And then I want to send a message from my main thread to the above thread so that I can handle the message in a non-expensive way. So as to not interrupt the main thread.

Like:

 // Main Thread

 while(true) {
     MSG msg;
     while(GetMessage(&msg, NULL, 0, 0)) {
          TranslateMessage(&msg);
          if(msg.message == WM_PAINT) {
              PostThreadMessage(); // How do I pass the thread id into the function?
          } else {
               DispatchMessage(&msg);
          }
     }
}

The summary of the problem is that PostThreadMessage requires a thread-id to be passed in as a parameter, now std::thread::get_id doesn't provide it in a "DWORD convertible format". So then I can't pass the thread's id as a parameter.

My question is: How would I pass the thread id as a parameter to PostThreadMessage?

CodePudding user response:

You can get the underlying, "Windows-style" thread handle for a std::thread object by calling its native_handle() member function. From that, you can retrieve the thread's ID by calling the GetThreadId WinAPI function, and passing that native handle as its argument.

Here's a short code snippet that may be what you'd want in the case you've outlined:

    auto tHandle = thread_not_main.native_handle(); // Gets a "HANDLE"
    auto tID = GetThreadId(tHandle);                // Gets a DWORD ID
    if (msg.message == WM_PAINT) {
        PostThreadMessage(tID, msg, wParam, lParam);
    }
    else {
        DispatchMessage(&msg);
    }
    //...

CodePudding user response:

std::thread does not expose the Win32 Thread ID that PostThreadMessage() wants.

The best way to handle this issue is to 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;
};

auto thread_func = [](threadInfo &info){
    info.id = GetCurrentThreadId();
    info.hasId.notify_one();

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        // Do appropriate stuff depending on the message
    }
};

...

threadInfo info;
std::thread thread_not_main(thread_func, std::ref(info));
info.hasId.wait();
...
PostThreadMessage(info.id, ...);

CodePudding user response:

Solution:

You can use the native_handle() member function to get the underlying platform-specific handle of the thread, and then pass that to PostThreadMessage():

std::thread thread_not_main = std::thread(thread_func);

...

PostThreadMessage(thread_not_main.native_handle(), WM_PAINT, 0, 0);
  • Related