gpt4 book ai didi

c++ - 我怎样才能使公共(public)共享对象的访问线程安全?

转载 作者:行者123 更新时间:2023-11-30 05:02:53 24 4
gpt4 key购买 nike

我搜索了整个 SO 论坛,但找不到任何合理的答案。我知道可以通过使用互斥锁和信号量等同步机制使资源共享成为线程安全的,但我的问题是不同的。假设您有一个 Logger 记录器 对象。它通过引用传递给所有正在运行的线程。此 logger 对象有一个 Logger::log 函数,其中资源(日志文件)由多个线程访问。我可以使用该方法用互斥量包装这个关键部分,以防止竞争条件。但是,如何防止多个线程访问共享的 Logger logger 对象时可能发生的竞争条件。我可以将一个通用互斥锁与 Logger logger 对象一起传递,并尝试在使用它之前获取该对象,但该解决方案并不优雅。在这个给定的场景中防止竞争条件的最好方法是什么?

最佳答案

更多与Single Responsibility Principle同步和 not to pay for what you dont use 的 C++ 思想是让 Logger 类只负责日志记录。想象一下,您想重用它来登录单线程应用程序 - 那么为什么要支付额外的同步费用。

当然,对于多线程应用程序——您将需要线程之间的同步机制。实现此目的的一种好方法是使用 Decorator Design Pattern - 如下所示:

class ILogger 
{
public:
virtual ~ILogger() = default;

// as many log methods as you need
virtual void log(args) = 0;
};

然后让您的 Logger 派生自并实现 ILogger

然后定义为其添加同步的装饰器:

class SynchronizedLogger : public ILogger 
{
public:
SynchronizedLogger (ILogger& logger) : logger(logger) {}

// as many log methods as you need
void log(args) override
{
std::lock_guard<std::mutex> lock(logGuard);
logger.log(args);
}

private:
std::mutex logGuard;
ILogger& logger;
};

您只需确保所有将使用日志记录的线程在 SynchronizedLogger 构造之后启动并在其销毁之前停止:

int main() {
Logger logger{...};
SynchronizedLogger syncLogger{logger};

std::thread t1([&syncLogger] { syncLogger.log("T1"); });
std::thread t2([&syncLogger] { syncLogger.log("T2"); });
std::thread t3([&syncLogger] { syncLogger.log("T3"); });
std::thread t4([&syncLogger] { syncLogger.log("T4"); });

t1.join();
t2.join();
t3.join();
t4.join();
}

关于c++ - 我怎样才能使公共(public)共享对象的访问线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49640384/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com