Tôi tạo ra giao diện đơn giản hóa riêng của tôi về boost::thread_group
để làm công việc này:
class ThreadGroup : public boost::noncopyable
{
private:
boost::thread_group group;
std::size_t maxSize;
float sleepStart;
float sleepCoef;
float sleepMax;
std::set<boost::thread*> running;
public:
ThreadGroup(std::size_t max_size = 0,
float max_sleeping_time = 1.0f,
float sleeping_time_coef = 1.5f,
float sleeping_time_start = 0.001f) :
boost::noncopyable(),
group(),
maxSize(max_size),
sleepStart(sleeping_time_start),
sleepCoef(sleeping_time_coef),
sleepMax(max_sleeping_time),
running()
{
if(max_size == 0)
this->maxSize = (std::size_t)std::max(boost::thread::hardware_concurrency(), 1u);
assert(max_sleeping_time >= sleeping_time_start);
assert(sleeping_time_start > 0.0f);
assert(sleeping_time_coef > 1.0f);
}
~ThreadGroup()
{
this->joinAll();
}
template<typename F> boost::thread* createThread(F f)
{
float sleeping_time = this->sleepStart;
while(this->running.size() >= this->maxSize)
{
for(std::set<boost::thread*>::iterator it = running.begin(); it != running.end();)
{
const std::set<boost::thread*>::iterator jt = it++;
if((*jt)->timed_join(boost::posix_time::milliseconds((long int)(1000.0f * sleeping_time))))
running.erase(jt);
}
if(sleeping_time < this->sleepMax)
{
sleeping_time *= this->sleepCoef;
if(sleeping_time > this->sleepMax)
sleeping_time = this->sleepMax;
}
}
return *this->running.insert(this->group.create_thread(f)).first;
}
void joinAll()
{
this->group.join_all();
}
void interruptAll()
{
#ifdef BOOST_THREAD_PROVIDES_INTERRUPTIONS
this->group.interrupt_all();
#endif
}
std::size_t size() const
{
return this->group.size();
}
};
Dưới đây là một ví dụ về sử dụng, rất giống với boost::thread_group
với sự khác biệt chính là việc tạo ra các chủ đề là một điểm chờ đợi:
{
ThreadGroup group(4);
for(int i = 0; i < 15; ++i)
group.createThread(aFunctionToExecute);
} // join all at destruction
Cuối cùng kết thúc với một cái gì đó như thế này: Tôi có một threadpool trong đó tôi đăng ký tất cả các công việc. Sau đó, tôi tạo ra các chủ đề n và chuyển làm đối số cho mỗi thread luồng. Mỗi luồng sẽ kiểm tra xem có công việc nào còn lại không. Nếu có, chỉ cần có một công việc để thực thi. Nếu không, luồng sẽ kết thúc. Bằng cách này, chúng ta chỉ cần tạo n luồng chứ không phải một luồng cho mỗi công việc (một công việc kết thúc, một luồng mới được tạo ra). –