
Hi, boost experts! This is my first mail. Although I am not boost newbee, I am indeed new to the boost community. == I was using Boost.Asio for a long time, for *Async Network I/O*, but up till recently, I made an amazing discover that Boost.Asio is NOT ONLY a Network library, but indeed a very *general* toolkit for building concurrent algorithm. I made the first discover when my friend show up an concurrent sum ``` #include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <future> template <typename RAIter> int parallel_sum(RAIter beg, RAIter end) { typename RAIter::difference_type len = end-beg; if(len < 1000) return std::accumulate(beg, end, 0); RAIter mid = beg + len/2; auto handle = std::async(std::launch::async, parallel_sum<RAIter>, mid, end); int sum = parallel_sum(beg, mid); return sum + handle.get(); } int main() { std::vector<int> v(10000, 1); std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n'; } ``` Here the actual calculations are done async and concurrently. But, the problem remains: ** The total threads that this algorithm spawn is not predictable and not configurable. ** And that's why we will not like such algorithm altogether. Days later, when I am review an old code that was doing an *async directory walk through* , I soon discover an general *concurrency ready* algorithm that the number of threads utilized can be fully controlled. The code utilized *any number of threads that is doing io_service::run()* Here is the good old demo that uses recursive algorithm : ``` // this is sequential recursing version void hanoi_sync(int n, char A, char B, char C) { if (n == 1) { printf("Move disk %d from %c to %c\n", n, A, C); } else { hanoi_sync (n-1, A, C, B); printf("Move disk %d from %c to %c\n", n, A, C); hanoi_sync (n-1, B, A, C); } } ``` But with Boost.Asio, we turn it into parallelism algorithm: ``` // concurrent hannoi tower solver void hanoi_async(boost::asio::io_ service& io, int n, char A, char B, char C) { if (n == 1) { printf("thread id %d, Move disk %d from %c to %c\n", boost::this_thread::get_id(), n, A, C); } else { io.post(boost::bind(&hannoi_async, boost::ref(io), n-1, A, C, B)); printf("thread id %d, Move disk %d from %c to %c\n", boost::this_thread::get_id(), n, A, C); io.post(boost::bind(&hannoi_async, boost::ref(io), n-1, B, A, C)); } } ``` Thanks to the amazing io_service.post, we can now turing any (if not mostly) *recursing code* into *parallelism code*. And the threads that used by such *parallelism code* is fully controlled. If one thread is calling io_service::run(), then it is simple an async version of the sequential recursing one, if more that one thread is doing io_service::run(), then you know that the job is now run in parallel. And yet there needs only one place to control how may threads is used. Want it to be faster? spawn more threads to call io_service::run()! The code will *automatically* use all threads that you have allocated to Boost.Asio. I am *not sure* if anyone else has made such discovery, anyway, comment is welcomed.