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

标签 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

}

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

最佳答案

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

要完成这一切,您的线程必须执行一个运行循环的函数。您可以使用 condition variable等待条件,即作业请求或停止命令。条件变量的优点是所有线程同步都为您完成。您只需将条件指定为谓词。将某些东西放入队列必须是一个原子操作。您可以使用 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;
};

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

关于c++ - 如何在 C++ 的类构造函数中使用线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61373945/

相关文章:

c++ - 带有 std::map 错误函数调用的 boost::factory

c++ - 在 C++ 中以毫秒为单位在时间戳上应用公式总是给我 0?

c++ - 'struct Node' 的无效使用/转发声明

c++ - 在做其他事情的同时用c++播放声音

multithreading - WP7 App 从服务和更新 UI 更新可观察集合

java - 如何退出包含Java的Callable ExecutiorService MultiThreading的循环(Android)

C++ 编译器说 "inconsistent deduction for auto return type"

使用 `pthread_create` 创建用户级线程或内核级线程?

caching - 在仿真中同步两个内核的方法

c - 新手线程问题 (FFTW)