如何避免在多线程应用程序 C++ 中缓存数据

How to avoid cached data in multithread application C++

谁能在下一刻澄清一下。我看到一些 std::queue 用于多线程目的的实现,其中 pushing/poping/erasing 元素的所有操作都受互斥锁保护,但是当我看到它时,我想象下一个场景:我们有两个线程(thread1 和 thread2),它们运行 在处理器的不同内核上,因此它们具有不同的 L1 缓存。我们有下一个队列:

struct Message {
    char* buf;
    size_t size;
};
std::queue<Message> messageQueue;

Thread1 将一些元素添加到队列中,然后 thread2 尝试使用 front() 方法访问一个元素,但是如果那块内存之前是为处理器的这个核心缓存的(所以 size 变量可能不会指示当前的) buf 变量的大小,或者 buf 指针可能持有错误的(未更新的)地址)? 我在服务器端设计 client/server 应用程序时遇到这样的问题。在我的应用程序服务器中是 运行 在一个线程中,它直接与套接字一起工作,当它接收到新消息时,它为该消息分配内存并将该消息添加到某个消息队列,然后其他线程访问该队列,处理消息,然后将其删除。我总是害怕缓存问题,因此我创建了自己的带有易失指针的队列实现。 处理这些事情的正确方法是什么?我必须避免使用带锁的 std::list、std::queue 吗?如果这个问题是不可能的,你能解释一下为什么吗?

只要您在可能以线程方式访问/更新的任何地方使用它,您就可以安全地使用互斥锁。这意味着对于此示例,添加到列表中/从列表中删除/解析列表是受互斥保护的。

您还必须注意存储在队列中的对象受到适当保护。

此外,请不要使用 char *。这就是 std::string 的目的。

这不是你的问题。您正在编写 C++ 代码。确保您的代码使 CPU 及其缓存做正确的事情是编译器的工作,而不是您的。您只需遵守所使用的任何线程标准的规则。

But if i lock some mutex, how can i be shure, that this memory isn't cached, or mutex locking somehow guarantee reading directly from the memory?

你不能。这是一件好事。缓存 大量 提高了性能,而主内存 非常 慢。幸运的是,现代 CPU 您可能会在其上编写多线程代码,但不会要求您像那样牺牲性能。他们有令人难以置信的复杂优化,例如缓存一致性硬件和预取固定,以避免对性能造成太大影响的事情。您想要的是让您的代码正常工作,而不是让它工作得很糟糕。