我成功测试了一个关于boost io_service的例子:
for(x = 0; x < loops; x++)
{
// Add work to ioService.
for (i = 0; i < number_of_threads; i++)
{
ioService.post(boost::bind(worker_task, data, pre_data[i]));
}
// Now that the ioService has work, use a pool of threads to service it.
for (i = 0; i < number_of_threads; i++)
{
threadpool.create_thread(boost::bind(
&boost::asio::io_service::run, &ioService));
}
// threads in the threadpool will be completed and can be joined.
threadpool.join_all();
}
这将循环几次并且需要一点点长,因为每次为每个循环创建线程。
有没有办法创建所有需要的线程。 然后在循环中发布每个线程的工作。 工作结束后,需要等到所有线程完成工作后才能完成工作!
这样的事情:
// start/create threads
for (i = 0; i < number_of_threads; i++)
{
threadpool.create_thread(boost::bind(
&boost::asio::io_service::run, &ioService));
}
for(x = 0; x < loops; x++)
{
// Add work to ioService.
for (i = 0; i < number_of_threads; i++)
{
ioService.post(boost::bind(worker_task, data, pre_data[i]));
}
// threads in the threadpool will be completed and can be joined.
threadpool.join_all();
}
答案 0 :(得分:2)
这里的问题是你的工作线程会在创建后立即完成,因为没有工作要做。 io_service::run()
将立即返回,因此,除非您在所有工作线程都有机会呼叫run()
之前设法潜入其中一个后呼叫,否则它们将立即完成。
解决此问题的两种方法:
run()
。只有在作品发布后才能解锁。io_service::work
对象阻止run
返回。您可以在发布所有内容后销毁工作对象(并且必须在再次尝试join
工作人员之前执行此操作)。答案 1 :(得分:0)
循环不是真正有用的。
这是一个更好的解决方法。 我在回调中获取数据:
void worker_task(uint8_t * data, uint32_t len)
{
uint32_t pos = 0;
while(pos < len)
{
pos += process_data(data + pos);
}
}
void callback_f(uint8_t *data, uint32_t len)
{
//split data into parts
uint32_t number_of_data_per_thread = len / number_of_threads;
// Add work to ioService.
uint32_t x = 0;
for (i = 0; i < number_of_threads; i++)
{
ioService.post(boost::bind(worker_task, data + x, number_of_data_per_thread));
x += number_of_data_per_thread ;
}
// Now that the ioService has work, use a pool of threads to service it.
for (i = 0; i < number_of_threads; i++)
{
threadpool.create_thread(boost::bind(
&boost::asio::io_service::run, &ioService));
}
// threads in the threadpool will be completed and can be joined.
threadpool.join_all();
}
因此,从主机应用程序(媒体流)调用此回调非常快。如果正在进行的len足够大,则线程池是有意义的。这是因为工作时间高于线程的初始化时间并开始运行。
如果数据的len很小,则线程池的优势就会丢失,因为线程的初始化和启动需要花费更多的时间来处理数据。
现在问题是,是否可以让线程已经运行并等待数据。如果调用回调,则将数据推送到线程并等待完成。线程数是常量(CPU计数)。 因为它是来自主机应用程序的回调,所以指向数据的指针仅在回调函数中有效。这就是我必须等到所有线程都完成工作的原因。
即使在其他线程开始之前,线程也可以在获取数据后立即开始工作。没有同步问题,因为每个线程都有自己的数据存储区。