首页 > 解决方案 > 最接近`std::atomic的是什么`?

问题描述

我是新手std::atomic。如果我理解正确的话,这样的变量一次不能被多个线程访问,如果线程试图这样做,它们就会被迫轮流。

我有一个std::vector<std::string>需要原子化的东西。最简单、最简单的方法是什么?

我有 2 个线程。一个偶尔将字符串推入向量,另一个线程连续读取然后擦除向量中的所有字符串。

线程 1,DLL 1

// about one per second
// this function is exported from DLL 2
myVector.push_back(myString);

线程 2,DLL 2

 while (true) {
        if (myVector.size() > 0) {
            std::string myString = myVector.at(0);
            std::string myCopy;
            myCopy.assign(myString);
            myVector.erase(myVector.begin());
        }
}

标签: c++multithreadingthread-safetystdvectorstdatomic

解决方案


拥有“最简单、最愚蠢的东西”的目标和处理复杂数据结构的目标是atomic相互矛盾的。

追求目标的一种方法是采用基于锁的方法。评论暗示了这一点。通常,基于锁的方法有其自身的警告(有死锁和饥饿),但对于您的情况,它会起作用,尽管可能仍然不是最佳的。

您需要的似乎是一个生产-消费者队列。单一生产者,单一消费者。


如果您期望高性能,它应该是无锁的、基于环形缓冲区的。

boost::lockfree::spsc_queue是一种可能的实现方式。还有其他实现。

此外,您可能希望避免字符串分配并使用boost::lockfree::spsc_queue<char>. 和 . 分隔字符串\0

如果您想要更快,您可能有自己的实现,针对您的场景进行了优化。


但是,如果您说“一个偶尔将字符串推入向量”,并且偶尔表示不经常,您可能需要基于锁的队列。

Boost.Thread 有同步队列——实验。还有其他实现。

mutex不用/直接用/的好处就是不用condition_variable自己写同步,真的很符合“最简单,最傻逼的事情”


我实际上在我的程序中实现了混合方法。当它需要等待时变成基于锁的,否则是无锁的。我还没有看到一个好的开源实现,但我想看看。


推荐阅读