参考来源https://www.gamedev.net/blogs/entry/2249317-a-guide-to-getting-started-with-boostasio/
Example 3a
asio简单运行使用:
#include <iostream>
#include <asio.hpp>
#include <thread>
#include <vector>
#include<mutex>
#include <functional>
#include <chrono>
std::mutex global_lock;
void workerThread(std::shared_ptr<asio::io_service> io_service ){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" start"<<std::endl;
global_lock.unlock();
io_service->run();
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" end"<<std::endl;
global_lock.unlock();
}
size_t fib(size_t n){
if(n<=1)
return n;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
return fib(n-1)+fib(n-2);
}
void CalculateFib(size_t n){
global_lock.lock();
std::cout<<std::this_thread::get_id()<< "calculating fib("<<n<<")"<<std::endl;
global_lock.unlock();
size_t f=fib(n);
std::cout<<std::this_thread::get_id()<<"result ="<<f<<std::endl;
}
int main(int argc,char * argv[]){
std::shared_ptr<asio::io_service> io_service(
new asio::io_service);
std::shared_ptr<asio::io_service::work> work(
new asio::io_service::work(*io_service));
std::cout<<"Press Enter to exit"<<std::endl;
std::vector<std::thread> ntid;
for(int i=0;i<2;i++)
{
ntid.push_back(std::thread(workerThread,io_service));
}
io_service->post(std::bind(CalculateFib,3));
io_service->post(std::bind(CalculateFib,4));
io_service->post(std::bind(CalculateFib,5));
std::cin.get();
io_service->stop();
for(auto &iter:ntid){
iter.join();
}
return 0;
}
结果如下:
Example 3b
post()和dispatch()的区别:Dispatched events can execute from the current worker thread even if there are other pending events queued up. The posted events have to wait until the handler completes before being allowed to be executed.
#include <iostream>
#include <asio.hpp>
#include <thread>
#include <vector>
#include<mutex>
#include <functional>
#include <chrono>
std::mutex global_lock;
void workerThread(std::shared_ptr<asio::io_service> io_service ){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" start"<<std::endl;
global_lock.unlock();
io_service->run();
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" end"<<std::endl;
global_lock.unlock();
}
void dispatch(int x){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<__FUNCTION__<<x<<std::endl;
global_lock.unlock();
}
void post(int x){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<__FUNCTION__<<x<<std::endl;
global_lock.unlock();
}
void run(std::shared_ptr<asio::io_service>io_service){
for(int i=0;i<4;i++){
io_service->dispatch(std::bind(dispatch,i*2));
io_service->post(std::bind(post,i*2+1));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main(int argc,char * argv[]){
std::shared_ptr<asio::io_service> io_service(
new asio::io_service);
std::shared_ptr<asio::io_service::work> work(
new asio::io_service::work(*io_service));
std::cout<<"Press Enter to exit"<<std::endl;
std::vector<std::thread> ntid;
for(int i=0;i<1;i++)
{
ntid.push_back(std::thread(workerThread,io_service));
}
io_service->post(std::bind(run,io_service));
std::cin.get();
io_service->stop();
for(auto &iter:ntid){
iter.join();
}
return 0;
}
结果如下:
Example 4a
strand定义了事件处理程序的严格顺序调用!This is because the strand object is correctly serializing the event processing to only one thread at a time. It is very important that we notice that strand does not serialize work through only one thread either.
#include <iostream>
#include <asio.hpp>
#include <thread>
#include <vector>
#include<mutex>
#include <functional>
#include <chrono>
std::mutex global_lock;
void workerThread(std::shared_ptr<asio::io_service> io_service ){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" start"<<std::endl;
global_lock.unlock();
io_service->run();
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" end"<<std::endl;
global_lock.unlock();
}
void printNum(int x){
std::cout<<"["<<std::this_thread::get_id()<<"] "<<__FUNCTION__<<" "<<x<<std::endl;
}
int main(int argc,char * argv[]){
std::shared_ptr<asio::io_service> io_service(
new asio::io_service);
std::shared_ptr<asio::io_service::work> work(
new asio::io_service::work(*io_service));
asio::io_service::strand strand(*io_service);
std::cout<<"Press Enter to exit"<<std::endl;
std::vector<std::thread> ntid;
for(int i=0;i<2;i++)
{
ntid.push_back(std::thread(workerThread,io_service));
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
for(int i=0;i<50;i++){
//io_service->post(std::bind(printNum,i)); //结果如图1所示
strand.post(std::bind(printNum,i)); //结果如图2所示
}
std::cin.get();
io_service->stop();
for(auto &iter:ntid){
iter.join();
}
return 0;
}
Example 4b
如果采用wrap包装函数,会有如下现象。--This is because the work we are passing is guaranteed to be executed serially, but there is no guarantee to which the order of the work actually takes place as a result of the API functions we are using!
#include <iostream>
#include <asio.hpp>
#include <thread>
#include <vector>
#include<mutex>
#include <functional>
#include <chrono>
std::mutex global_lock;
void workerThread(std::shared_ptr<asio::io_service> io_service ){
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" start"<<std::endl;
global_lock.unlock();
io_service->run();
global_lock.lock();
std::cout<<std::this_thread::get_id()<<" end"<<std::endl;
global_lock.unlock();
}
void printNum(int x){
std::cout<<"["<<std::this_thread::get_id()<<"] "<<__FUNCTION__<<" "<<x<<std::endl;
}
int main(int argc,char * argv[]){
std::shared_ptr<asio::io_service> io_service(
new asio::io_service);
std::shared_ptr<asio::io_service::work> work(
new asio::io_service::work(*io_service));
asio::io_service::strand strand(*io_service);
std::cout<<"Press Enter to exit"<<std::endl;
std::vector<std::thread> ntid;
for(int i=0;i<4;i++)
{
ntid.push_back(std::thread(workerThread,io_service));
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
io_service->post(strand.wrap(std::bind(printNum,1)));
io_service->post(strand.wrap(std::bind(printNum,2)));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
io_service->post(strand.wrap(std::bind(printNum,3)));
io_service->post(strand.wrap(std::bind(printNum,4)));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
io_service->post(strand.wrap(std::bind(printNum,5)));
io_service->post(strand.wrap(std::bind(printNum,6)));
std::cin.get();
io_service->stop();
for(auto &iter:ntid){
iter.join();
}
return 0;
}