C++ C++;11有多线程问题
所以我开始写一个游戏,我想要一个不同线程的记录器。我的方法是这样的:让一个类“Logger”,在构造函数中运行一个线程,在线程中有一个循环在运行,它不断地检查stringstream的数据。stringstream是一个静态变量,所以我在程序的入口点运行logger,然后每当我需要记录一些东西时,我调用一个静态方法写入静态stringstream,该方法在线程中每隔100ms读取一次。所以我想知道这种方法在游戏编程中是否可行,如果它有一点好,我应该怎么做 尝试了这个,但失败了(不知何故,某些东西在睡眠后立即抛出一个未处理的异常(100),并且没有继续循环…)C++ C++;11有多线程问题,c++,multithreading,c++11,C++,Multithreading,C++11,所以我开始写一个游戏,我想要一个不同线程的记录器。我的方法是这样的:让一个类“Logger”,在构造函数中运行一个线程,在线程中有一个循环在运行,它不断地检查stringstream的数据。stringstream是一个静态变量,所以我在程序的入口点运行logger,然后每当我需要记录一些东西时,我调用一个静态方法写入静态stringstream,该方法在线程中每隔100ms读取一次。所以我想知道这种方法在游戏编程中是否可行,如果它有一点好,我应该怎么做 尝试了这个,但失败了(不知何故,某些东西
类记录器
{
私人:
流出的液体;
字符串文件名;
螺纹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();
}