2

I'm using boost 1.51 on multiple platforms and compilers without C++11.

In my main thread I have a very long, expensive to copy, std::string veryLongString, that I need to pass to a new thread for processing.
After the new thread is created I have no more use for veryLongString on the main thread so I'd like to move it into the boost::thread ctor.
The main thread, or the scope of veryLongString may end before the new thread completes, so passing by reference (e.g. with boost::ref) is not an option.

Obviously, if veryLongString was created as a shared_ptr<std::string> then I could just copy the shared_ptr into the thread ctor, but it wasn't, so I'd need to copy it anyway.

How can I [boost::]move() veryLongString into the boost::thread ctor (probably using via boost::bind)? Is this possible?

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
  • I'm not sure I understand your question completely. But if I do, then once the main thread goes out of scope veryLongString goes along with it, destroying the string and creating a dangling ref inside the new thread. I updated the question to reflect this. – Adi Shavit Oct 04 '12 at 09:36
  • It's sounds like you create a thread for some special processing, and not a "daemon" thread that is detached from the main thread. Therefore the scenario that the main thread would exit before the processing threads sound suspicious. – Some programmer dude Oct 04 '12 at 09:40
  • As for your problem, why not pass the string as a reference to the constructor, and in the constructor use `boost::move` to move the contents to an internal string? – Some programmer dude Oct 04 '12 at 09:41
  • @Joachim Pileborg: actually, it is an async call that is sent off to do it's work. It will call a completion handler/continuation when it's done. The main thread, does not really exit but `veryLongString` does go out of scope to handle other things. BUT, I was using a function to do the work. If I use an callable-object I can do what you suggested, I don't know why I didn't think of that! I don't even need `boost::mov`e, I can just `swap` the strings. Put your 2nd comment as an answer and I'll mark it as *the* answer. – Adi Shavit Oct 04 '12 at 09:48

2 Answers2

1

If the string is expensive to copy, pass something holding it but less expensive to copy. For example, you can use a shared_ptr<std::string>. You can pass the shared pointer to a suitable wrapper which calls the function you actually want to get called (and probably taking the argument by reference or const reference).

To get the string into a shared pointer you might need to move it there:

shared_ptr<std::string> ptr(new std::string);
ptr->swap(your_long_string);
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 3
    This, indeed, works fine. Just a small optimization is to use `shared_ptr ptr = make_shared()` instead of `new`. – Adi Shavit Oct 04 '12 at 10:42
  • Wouldn't the implementation of swap still make a copy on non c++11 compilers? So solving the issues mentioned? – André Oct 04 '12 at 11:33
  • The copy is of the `shared_ptr` not the `std::string`. So momentarily the ref. count will be 2, until the calling thread instance goes out of scope. – Adi Shavit Oct 04 '12 at 11:40
  • 1
    I might completely miss the point here, but if swap was called on the shared_ptr it should be called like ptr.swap(your_long_string). That would not compile since your_long_string is not a shared_ptr. – André Oct 04 '12 at 12:14
  • 1
    There are two `swap()` which could be used: `ptr.swap(p)` would swap shared pointers, `ptr->swap(s)` swaps the pointed to string with another string. `std::string` has a `swap()` member just exchanging the internal pointers (unless there are small strings involved which may require moving characters). – Dietmar Kühl Oct 04 '12 at 14:00
0

You could pass it as a reference to the constructor, and in the constructor use move (or even swap) to "move" the string.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I just tried this. It is not as simple as I initially thought. Although the string is "moved" into the functor, passing the functor into the thread requires a functor copy (can't pass by ref), so that I need to write a special copy-ctor that actually moves it instead of copying. – Adi Shavit Oct 04 '12 at 10:02