I'm trying to capture thread_pool object in a lambda function. This lambda function is called inside a thread. Upon this call, it creates(obtains) a new thread with asio::post. However, it throws segmentation fault. I tried create weak ptr with shared_ptr<thread_pool> but it didn't work as well. Simple example written below,
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
void thread1(std::function<void()> createThread) {
createThread();
}
void thread2() {
cout << "You made it" << std::endl;
}
int main(int argc, char **argv) {
boost::asio::thread_pool pool(std::thread::hardware_concurrency());
std::function<void()> createThread;
createThread = [&pool] () {
boost::asio::post(pool, boost::bind(thread2));
return true;
};
boost::asio::post(pool, boost::bind(thread1, createThread));
pool.join();
}
It works if I create another thread_pool object inside the lambda function. However, this is not the right way to do this. Therefore, I am open for your suggestions.
Edit: Added libraries to code snippet and removed while loop.
I'd simplify:
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
void thread1(std::function<void()> createThread) {
createThread();
while (true) {
std::cout << "Sleeping" << std::endl;
sleep(1);
}
}
void thread2() { std::cout << "You made it" << std::endl; }
int main() {
boost::asio::thread_pool pool;
post(pool,
boost::bind(thread1, [&pool]() { post(pool, boost::bind(thread2)); }));
pool.join();
}
Note the endl
that forces stdout to flush, which helps getting results you can expect.
There's a code smell with:
bind
expressionscreateThread
doesn't (create a thread) Applying these:
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
using Executor = boost::asio::thread_pool::executor_type;
void task_loop(Executor ex, std::function<void()> task) {
while (true) {
post(ex, task);
sleep(1);
}
}
void task_function() { std::cout << "Task executes" << std::endl; }
int main() {
boost::asio::thread_pool pool;
post(pool, boost::bind(task_loop, pool.get_executor(), task_function));
pool.join();
}
Prints each second:
Task executes
Task executes
...
Is this one what you look for? :
typedef std::unique_ptr<boost::asio::io_service::work> work_ptr;
std::atomic<bool> closeFlag(false);
int main(int argc, char** argv) {
boost::asio::io_service service;
// keep the workers occupied
work_ptr work(new boost::asio::io_service::work(service));
boost::thread_group workers;
for(size_t i = 0; i < std::thread::hardware_concurrency(); ++i) {
workers.create_thread([&service]() {
service.run();
});
}
service.post([] { std::cout << "You made first job"; });
service.post([] { std::cout << "You made second job"; });
while(!closeFlag) {
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
service.stop();
work.reset(); // destroy work object: signals end of work
workers.join_all(); // wait for all worker threads to finish
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.