
On Mar 27, 2007, at 1:11 PM, Howard Hinnant wrote:
vector<thread> v; ... fill with threads ... for (auto i = v.begin(), e = v.end(); i != e; ++i) if (i_feel_like_it) i->detach(); ... // need new thread now, go look for a detached one and use it auto i = v.begin(); for (auto e = v.end(); i != e; ++i) if (i->is_detached()) // N2184 spells this i->get_id() == thread::id() break; if (i != v.end()) *i = std::thread(f); // recycle detached thread else v.push_back(std::thread(f));
In this use case, you're still recycling threads, as in my previous use case. But here there is an opportunity for many threads to not get recycled for a long time, and perhaps forever.
<sigh> And this use case is making me nervous about join not implicitly detaching...
I'm beginning to think: multijoin() const { // Don't want to pretend to join with non-existent // (or detached) thread, make noise if (handle_ == 0) throw ?; while (!tl->done) tl->cv1.wait(); } join() { multijoin(); detach(); } Rationale: join() has the semantics of pthread_join(), and I think should be the default (easier name). Thread resource cleanup needs to be done at intuitive times, and with vector<thread> just around the corner I fear the potential for a lot of non-deallocated (delayed) thread resources is very real. However the only cost to providing multijoin is a bigger interface (which should certainly be considered). The previous sentence assumes not building on pthread_cancel. Otherwise we need to go Peter's route of extending the pthread interface for multijoin (which I think is called pthread_join2_np). The pthreads people have a lot of experience in this interface. No, they didn't get it perfect. But we really need to be careful in deviations from it. I'm still thinking about how this should cross with try/timed... -Howard