Asio_3/4

参考来源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;

}

结果如下:


image.png

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;

}

结果如下:


image.png

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;

}
图1.png
图2.png

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;

}
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容