如何在C++中的类构造函数中使用线程?

val*_*ian 5 c++ multithreading

有没有可能的方法在类中使用线程,如下所示:

Class Logger // singleton class
{
//.... here is implemented thread logic 
{

void main()
{
   Logger& log = Logger::getInstance();
   log.writeMessage(); // this should execute in another thread
                       // also, all the other func from Logger class
                       // should execute in that second thread

   // ... some code -> executes in main thread

   log.deleteInstance(); // join threads

}
Run Code Online (Sandbox Code Playgroud)

我需要提一下,我是线程的新手。我只需要一个想法,这样我就可以开始思考它是如何运作的。

jig*_*ius 4

您所描述的是一个将在后台运行的工作线程。我不会每次调用时都启动一个新线程,WriteMessage()因为线程创建相当昂贵,并且启动和停止线程实际上会减慢程序的速度。相反,您可以在类的构造函数中启动一个线程并让它监视队列。您班级的其他客户端Logger可以使用该WriteMessage()函数将某些内容推送到队列中。记录器将检测到某些作业已到达并对其进行处理。最后,当您完成后,调用一个Stop()函数来停止线程。

要完成这一切,您的线程必须执行一个运行循环的函数。您可以使用条件变量来等待条件,即作业请求或停止命令。条件变量的优点是所有线程同步都为您完成。您只需将条件指定为谓词即可。将某些内容放入队列必须是原子操作。您可以为此使用std::lock_guard 。

Logger当工作线程在后台执行其工作时,您可以从主线程调用其他函数。那不是问题。

这是该类的一个实现Logger

#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <iostream>
#include <queue>

class Logger // singleton class
{
public:
    Logger() : mThread{}, mCV{}, mMutex{}, mQueue{}, mStop{ false }
    {
        mThread = std::thread(&Logger::Run, this); //create thread and execute Run()
    }

    ~Logger()
    {
        //Join thread
        if (mThread.joinable())
        {
            mThread.join();
        }
    }

    static Logger& getInstance() {
        static Logger logger;
        return logger;
    }

    void Stop()
    {
        {
            //Set the stop flag
            std::lock_guard<std::mutex> lk(mMutex);
            mStop = true;
        }
        mCV.notify_one();
    }

    void WriteMessage(const std::string& msg)
    {
        {
            //Push a request on the queue
            std::lock_guard<std::mutex> lk(mMutex);
            mQueue.push(msg);
        }
        mCV.notify_one();
    }

private:
    void Run()
    {
        while (true)
        {
            //Wait until some request comes or stop flag is set
            std::unique_lock<std::mutex> lock(mMutex);
            mCV.wait(lock, [&]() { return mStop || !mQueue.empty(); });

            //Stop if needed
            if (mStop)
            {
                break;
            }

            //Pop the job off the front of the queue
            std::string msg = std::move(mQueue.front());
            mQueue.pop();
            //Unlock the mutex
            lock.unlock();

            std::cout << msg << std::endl;
        }
    }

private:
    std::thread mThread;
    std::condition_variable mCV;
    std::mutex mMutex;
    std::queue<std::string> mQueue;
    bool mStop;
};
Run Code Online (Sandbox Code Playgroud)

工作版本在这里: https: //ideone.com/wYIaMY