【问题标题】:Moving an std::string into a boost::thread in C++03在 C++03 中将 std::string 移动到 boost::thread 中
【发布时间】:2012-09-25 07:10:12
【问题描述】:

我在没有 C++11 的多个平台和编译器上使用 boost 1.51。

在我的主线程中,我有一个很长、很昂贵的复制 std::string veryLongString,我需要将其传递给一个新线程进行处理。
创建新线程后,我不再使用主线程上的veryLongString,所以我想将其移动boost::thread ctor。
主线程或veryLongString 的范围可能在新线程完成之前结束,因此不能通过引用传递(例如使用boost::ref)。

显然,如果veryLongString 被创建为shared_ptr<std::string>,那么我可以将shared_ptr 复制到线程ctor 中,但事实并非如此,所以无论如何我都需要复制它。

我怎样才能[boost::]move() veryLongString 进入boost::thread ctor(可能通过boost::bind 使用)? 这可能吗?

【问题讨论】:

  • 我不确定我是否完全理解您的问题。但是如果我这样做了,那么一旦主线程超出范围,veryLongString 就会随之而来,破坏字符串并在新线程内创建一个悬空引用。我更新了问题以反映这一点。
  • 这听起来像是您为某些特殊处理创建了一个线程,而不是与主线程分离的“守护程序”线程。因此,主线程在处理线程之前退出的情况听起来很可疑。
  • 至于你的问题,为什么不将字符串作为引用传递给构造函数,并在构造函数中使用boost::move将内容移动到内部字符串?
  • @Joachim Pileborg:实际上,这是一个异步调用,被发送出去完成它的工作。完成后它将调用完成处理程序/延续。主线程并没有真正退出,但veryLongString 确实超出了处理其他事情的范围。但是,我正在使用一个函数来完成这项工作。如果我使用可调用对象,我可以按照您的建议做,我不知道为什么我没有想到这一点!我什至不需要boost::move,我只需swap 字符串即可。将您的第二条评论作为答案,我会将其标记为 the 答案。

标签: c++ boost boost-thread stdstring boost-move


【解决方案1】:

如果字符串的复制成本很高,则传递一些持有它但复制成本较低的东西。例如,您可以使用shared_ptr<std::string>。您可以将共享指针传递给合适的包装器,该包装器调用您实际想要调用的函数(并且可能通过引用或const 引用获取参数)。

要将字符串放入共享指针中,您可能需要将其移到那里:

shared_ptr<std::string> ptr(new std::string);
ptr->swap(your_long_string);

【讨论】:

  • 这确实很好用。只是一个小的优化是使用shared_ptr&lt;std::string&gt; ptr = make_shared&lt;std::string&gt;()而不是new
  • swap 的实现不会在非 c++11 编译器上复制吗?那么解决上面提到的问题呢?
  • 副本是shared_ptr,而不是std::string。所以暂时参考。 count 将为 2,直到调用线程实例超出范围。
  • 我可能完全错过了这里的重点,但是如果在 shared_ptr 上调用了 swap,它应该像 ptr.swap(your_long_string) 一样调用。这不会编译,因为 your_long_string 不是 shared_ptr。
  • 可以使用两个swap()ptr.swap(p) 将交换共享指针,ptr-&gt;swap(s) 将指向的字符串与另一个字符串交换。 std::string 有一个 swap() 成员只是交换内部指针(除非涉及可能需要移动字符的小字符串)。
【解决方案2】:

您可以将它作为对构造函数的引用传递,并在构造函数中使用move(甚至swap)来“移动”字符串。

【讨论】:

  • 我刚试过这个。它并不像我最初想象的那么简单。虽然字符串被“移动”到函子中,但将函子传递到线程中需要函子副本(不能通过 ref 传递),因此我需要编写一个特殊的 copy-ctor 来实际移动它而不是复制。
猜你喜欢
  • 2013-11-26
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 2013-07-14
  • 2020-12-21
  • 2012-10-20
  • 2018-04-14
  • 1970-01-01
相关资源
最近更新 更多