Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11有多线程问题_C++_Multithreading_C++11 - Fatal编程技术网

C++ C++;11有多线程问题

C++ C++;11有多线程问题,c++,multithreading,c++11,C++,Multithreading,C++11,所以我开始写一个游戏,我想要一个不同线程的记录器。我的方法是这样的:让一个类“Logger”,在构造函数中运行一个线程,在线程中有一个循环在运行,它不断地检查stringstream的数据。stringstream是一个静态变量,所以我在程序的入口点运行logger,然后每当我需要记录一些东西时,我调用一个静态方法写入静态stringstream,该方法在线程中每隔100ms读取一次。所以我想知道这种方法在游戏编程中是否可行,如果它有一点好,我应该怎么做 尝试了这个,但失败了(不知何故,某些东西

所以我开始写一个游戏,我想要一个不同线程的记录器。我的方法是这样的:让一个类“Logger”,在构造函数中运行一个线程,在线程中有一个循环在运行,它不断地检查stringstream的数据。stringstream是一个静态变量,所以我在程序的入口点运行logger,然后每当我需要记录一些东西时,我调用一个静态方法写入静态stringstream,该方法在线程中每隔100ms读取一次。所以我想知道这种方法在游戏编程中是否可行,如果它有一点好,我应该怎么做

尝试了这个,但失败了(不知何故,某些东西在睡眠后立即抛出一个未处理的异常(100),并且没有继续循环…)

类记录器
{
私人:
流出的液体;
字符串文件名;
螺纹T;
布尔跑;
静态串流;
无效运行();
公众:
记录器();
~Logger();
无效停止();
静态无效日志(字符串msg);
void join();
};
stringstream记录器::sstream;
记录器::记录器()
{
fileName=“log.txt”;
out=流(文件名);
如果(!out.is_open())
{
发帖信息(3);
}
运行=错误;
T=线程(&Logger::run,this);
}
记录器::~Logger()
{
out.close();
}
void记录器::run()
{
运行=真;
(跑步时)
{
如果(!sstream.str().empty())
{

当然,还有一个迫在眉睫的问题:

  • 没有会导致未定义行为的同步。您需要创建适当的同步,例如,为您
    std::mutex
    使用
    std::stringstream
    (我个人只想使用
    std::queue
    ,但这是另一个问题
  • 记录器线程不应该轮询输入。相反,它应该只对
    std::condition\u变量
    进行
    notify\u one()
    d以获取可用数据
  • 虽然它只是一个
    bool
    ,但运行
    的标记也需要同步!如果任何线程没有同步就使用另一个线程写入的变量,则这是一个数据竞争。对于
    running
    标记,您可能需要使用
    std::atomic

  • 这种方法还可以,但您应该考虑同步,如果两个不同的线程在同一时刻尝试调用
    log
    方法会怎么样?一个进行日志记录的线程可能应该从main not joined“It's not joined”中分离出来…嗯,那么为什么我在最后一个函数中看到T.join而不在任何地方分离:P,顺便说一句,我不是说你不应该只是一个建议如果有一个方法,这并不意味着它被使用了:谢谢你的答案。没有考虑第二部分,这是非常聪明的。但是还有一个问题,我对多线程+c++非常陌生,那么我该怎么做呢在stringstream上使用互斥锁?@VilmantasBašinovas:好吧,您只需在每次访问流之前锁定互斥锁,然后立即释放它。要自动化此过程,您需要使用
    std::unique_锁
    ,这是
    std::condition_变量
    等待所需的锁(您可能需要使用
    wait_-until()
    谓词检查流并运行
    标志)。注意,您需要
    通知
    当您触摸流或运行
    标志以使日志线程退出等待时。理论上我知道互斥锁是如何工作的,但我不知道如何实际使用它。比如如何在我的代码中实现它…/embarassed
    class Logger
    {
    private:
        ofstream out;
        string fileName;
        thread T;
        bool running;
    
        static stringstream sstream;
    
        void run();
    
    public:
        Logger();
        ~Logger();
    
        void stop();
    
        static void log(string msg);
    
        void join();
    };
    
    stringstream Logger::sstream;
    
    Logger::Logger()
    {
        fileName = "log.txt";
        out = ofstream(fileName);
        if (!out.is_open())
        {
            PostQuitMessage(3);
        }
        running = false;
        T = thread(&Logger::run, this);
    }
    
    Logger::~Logger()
    {
        out.close();
    }
    
    void Logger::run()
    {
        running = true;
        while (running)
        {
            if (!sstream.str().empty())
            {
                out << sstream.str();
                sstream.clear();
            }
            Sleep(100);
        }
    }
    
    void Logger::stop()
    {
        running = false;
    }
    
    void Logger::log(string msg)
    {
        Logger::sstream << "lel" << endl;
    }
    
    void Logger::join()
    {
        T.join();
    }