Boost,在io_service.post之前创建线程池
Boost, create thread pool before io_service.post
我成功地测试了一个关于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();
}
这里的问题是,您的工作线程将在创建后立即完成,因为没有工作要做。io_service::run()
将立即返回,因此,除非您设法在所有工作线程都有机会调用run()
之前潜入其中一个post调用,否则它们都将立即完成。
解决此问题的两种方法:
- 使用屏障阻止工人立即呼叫
run()
。只有在作品发布后才能解锁它们 - 使用
io_service::work
对象来防止run
返回。一旦发布了所有内容,就可以销毁工作对象(并且必须在尝试再次join
工作者之前销毁)
循环并不是真正有用的。
这是一个更好的工作方式。我在回调中获取数据:
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足够大,线程池是有意义的。这是因为工作时间高于线程和开始运行的初始时间。
如果数据的长度很小,那么线程池的优势就会丧失,因为初始化和启动线程比处理数据花费更多的时间。
现在可能的问题是,是否有可能让线程已经在运行并等待数据。如果回调被调用,则将数据推送到线程并等待其完成。线程数是恒定的(CPU计数)。因为它是来自主机应用程序的回调,所以指向数据的指针只有在回调函数中时才有效。这就是为什么我必须等到所有线程都完成工作。
线程可以在获取数据后立即开始工作,甚至在其他线程开始工作之前。并没有同步问题,因为每个线程都有自己的数据存储区。
相关文章:
- C++使用params创建线程函数会导致转换错误
- 为什么我不能在 while 循环中创建线程?
- 如何创建线程序列以按照启动顺序执行任务?
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- std::使用类成员函数创建线程 - 最佳实践
- CPP:如何使用需要指针的方法创建线程
- 使用 lambda 表达式创建线程时,如何为每个线程提供自己的 lambda 表达式副本
- C++,如何创建线程限制/受保护的变量和函数
- BOOST_LOG_SEV在创建线程后损坏async_read_some
- 为什么当我在构造函数中创建线程时,实例化对象和对象的指针的行为不同
- 如何通过调用类中的函数来创建线程
- 如何在Silverlight本机C 中创建线程
- 通过类构造函数创建线程
- C++:创建线程时出现问题;错误 C2672:"std::invoke":找不到匹配的重载函数
- 尝试在dll main中创建线程
- 如何在Linux上为C和C 创建线程安全LIB
- 如何在 dll 中创建线程 (c++)?
- 从调度队列块 [ swift / c++ ] 创建线程
- 从成员类功能创建线程
- 创建线程,但不要立即在 Linux 中运行它