【问题标题】:how to put std::string into boost::lockfree::queue (or alternative)?如何将 std::string 放入 boost::lockfree::queue (或替代)?
【发布时间】:2013-07-01 09:48:32
【问题描述】:

我正在尝试将std::strings 放入boost::lockfree::queues,以便我的线程可以使用新数据相互更新。

当我尝试使用boost::lockfree::queue<std::string> updated_data; 时,g++ 会说:

在 'class boost::lockfree::queue >' 的实例化中:

错误:静态断言失败:(boost::has_trivial_destructor::value)

错误:静态断言失败:(boost::has_trivial_assign::value)

我一直是shown generally what these errors mean,但我没有希望自己解决这个问题,因为我对 c++ 几乎是全新的。

是否有另一种方法可以使用lockfree 在线程之间传递文本数据?如果没有,请告诉我如何将std::string 放入boost::lockfree::queue

【问题讨论】:

    标签: c++ boost queue stdstring lock-free


    【解决方案1】:

    boost::lockfree::queue 文档明确指出,包含的 itemm 必须有一个简单的复制分配和析构函数,而 std::string 没有。

    如果你有一个生产者和一个消费者,你可以使用spsc_queue (http://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/spsc_queue.html),它只需要默认的可构造性和可复制性。

    如果您有多个生产者或消费者,您将被一个普通的锁定队列(或不使用动态分配的自定义字符串)卡住。

    【讨论】:

    • 谢谢,请注意 spsc_queue!
    【解决方案2】:

    我没有希望自己解决这个问题,因为我对 c++ 几乎是全新的。

    那么我想知道你为什么要搞乱诸如无锁队列之类的东西。

    是否有另一种方法可以使用lockfree 在线程之间传递文本数据?

    是的,您可以只在队列中存储一个指向数据的std::string* 指针,因为指针是一种普通类型,因此在队列中是允许的。等效地,您可以存储reference_wrapper<std::string>。问题是您需要将字符串存储在其他地方,以便能够指向它们,所以现在您所做的就是将问题移到其他地方(例如,您可以在每个线程中维护一个字符串列表, 并将指向外部管理字符串的指针存储在无锁队列中,但您不知道何时可以安全地从每个线程列表中删除 string,因此它会不断增长。)

    我建议您使用简单的std::queue<std::string> 并与boost::mutexboost::condition_variable 进行自己的同步,或者找到线程安全(不是无锁!)队列的现有实现。

    【讨论】:

    • 这得到了 +1,因为我什至没有考虑在队列中存储原始指针。
    • 已经做了什么,存储原始指针?它会将实际对象放在哪里?将非托管原始指针放在容器中通常是不好的做法,它太容易泄漏内存
    • 那么你去吧,你已经解决了问题,现在它只是一个simple matter of programming ;)
    • 警告:除非使用危险指针之类的技巧(无法释放旧的 std::strings),否则会泄漏内存
    • @Gracchus,我很高兴你确信这并不容易 :)
    【解决方案3】:

    如果将原始指针放入队列中,旧的std::strings 将被泄露,因为在不再需要它们时无法释放它们。这是因为没有锁就没有办法以线程安全的方式释放对象(除了一些技巧,如危险指针,boost::lockfree::queue 不使用)

    出于我不太了解的技术原因,boost::lockfree::queue 需要一个普通的赋值运算符和一个普通的析构函数,这意味着您的对象不能也不包含任何必须在其析构函数中释放内存的数据类型,例如 std::string .

    【讨论】:

    • 这并不完全正确:您可以将原始指针放入队列并在弹出指针时释放它们。例如queue->consume_all([](std::string* str) { do_something(str); delete str; });
    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2013-02-25
    • 2012-04-13
    相关资源
    最近更新 更多