Execute lambda with CreateThread

Issue

Is there a better way to use CreateThread than creating a free function each time for the sole purpose of casting lpParameter?

Are there any modern alternatives to CreateThread for creating persistent threads?

Edit: Perhaps you should just use std::async(lambda). I imagine that it’s just implemented with CreateThread. Maybe the answer to this question is looking up how std::async is implemented (assuming it’s a library feature).

DWORD WINAPI MyThreadFunction(
  _In_ LPVOID lpParameter
)
{
    ((MyClass*)lpParameter)->RunLoop();
}

void MyClass::LaunchThread()
{
    CreateThread( 
            NULL,                   // default security attributes
            0,                      // use default stack size  
            MyThreadFunction,       // thread function name
            this,          // argument to thread function 
            0,                      // use default creation flags 
            NULL);   // returns the thread identifier 
}

Solution

There are several mechanisms for achieving parallelism (std::async etc. as mentioned above).

But the modern one which is most similar to your original code with CreateThread is std::thread. It can be constructed with a global function, a lambda, or a class method (which seems the best fit for you):

m_thread = std::thread([this](){ RunLoop(); });  // pass a lambda

or

m_thread = std::thread(&MyClass::RunLoop, this); // pass a method

Note that a std::thread starts to run (potentially) when constructed. Also note that, std::async does not guarantee that it will run on a separate thread and even if it does run on a thread, it could be a thread from a pool. The behaviour might not be the same as with your original CreateThread.

Here’s a complete example of using std::thread (including cancellation):

#include <thread>
#include <chrono>
#include <atomic>
#include <iostream>

class MyClass
{
public:
    MyClass()  {}
    ~MyClass() { EndThread(); }

    void LaunchThread()
    {
        EndThread();    // in case it was already running
        m_bThreadShouldExit = false;
        // Start the thread with a class method:
        m_thread = std::thread(&MyClass::RunLoop, this);
    }

    void EndThread()
    {
        // Singal the thread to exit, and wait for it:
        m_bThreadShouldExit = true;
        if (m_thread.joinable())
        {
            m_thread.join();
        }
    }

    void RunLoop()
    {
        std::cout << "RunLoop started" << std::endl;
        while (!m_bThreadShouldExit)
        {
            std::cout << "RunLoop doing something ..." << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
        std::cout << "RunLoop ended" << std::endl;
    }

private:
    std::thread         m_thread;
    std::atomic_bool    m_bThreadShouldExit{ false };
};


int main()
{
    MyClass m;
    m.LaunchThread();
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    m.EndThread();
}

Possible output:

RunLoop started
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop ended

Answered By – wohlstad

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published