日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Boost基础]并发编程——asio网络库——定时器deadline_timer

發(fā)布時(shí)間:2025/5/22 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Boost基础]并发编程——asio网络库——定时器deadline_timer 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

asio庫基于操作系統(tǒng)提供的異步機(jī)制,采用前攝器設(shè)計(jì)模式(Proactor)實(shí)現(xiàn)了可移植的異步(或者同步)IO操作,而且并不要求使用多線程和鎖定,有些的避免了多線程編程帶來的諸多有害副作用(如條件競爭、死鎖等)。
目前asio主要關(guān)注網(wǎng)絡(luò)通信方面,使用大量的類和函數(shù)封裝了socket API,提供了一個(gè)現(xiàn)代C++風(fēng)格的網(wǎng)絡(luò)編程接口,支持TCP,ICMP,UDP等網(wǎng)絡(luò)通信協(xié)議。但asio的異步操作并不局限于網(wǎng)絡(luò)編程,他還支持串口讀寫,定時(shí)器,SSL等功能,而且asio是一個(gè)很好的富有彈性的框架,可以擴(kuò)展到其他有異步操作需要的領(lǐng)域。

asio概述

asio庫基于前攝模式(Proactor)封裝了操作系統(tǒng)的select,poll/epoll,kqueue,overlapped I/O等機(jī)制,實(shí)現(xiàn)了異步IO模型。他的核心類是io_service,相當(dāng)于前攝模式中的Proactor角色,asio的任何操作都需要有io_service的參與。
在同步模式下,程序發(fā)起一個(gè)IO操作,向io_service提交請求,io_service把操作轉(zhuǎn)給操作系統(tǒng),同步的等待。當(dāng)IO操作完成時(shí),操作系統(tǒng)通知io_service,然后io_service在把結(jié)果發(fā)回給程序,完成整個(gè)同步流程。這個(gè)處理流程與多線程join()等待方式很相似。
在異步模式下,程序除了要發(fā)起的IO操作,還要定義一個(gè)用于回調(diào)的完成處理函數(shù)。io_service同樣把IO操作轉(zhuǎn)交給操作系統(tǒng)執(zhí)行,但它不同步等待,而是立即返回。調(diào)用io_service的run()成員函數(shù)可以等待異步操作完成,當(dāng)異步操作完成時(shí)io_service從操作系統(tǒng)獲取執(zhí)行結(jié)果,調(diào)用完成處理函數(shù)。
asio不直接使用操作系統(tǒng)提供的線程,而且定義了一個(gè)自己的線程概念:strand,它保證在多線程的環(huán)境中代碼可以正確的執(zhí)行,而無需使用互斥量。io_serviec::strand::wrap()函數(shù)可以包裝在一個(gè)函數(shù)在strand中執(zhí)行。
IO操作會(huì)經(jīng)常使用到緩沖區(qū),asio庫專門用兩個(gè)類mutable_buffer和const_buffer來封裝這個(gè)概念,他們可以被安全的應(yīng)用在異步的讀寫操作中,使用自由函數(shù)buffer()能夠包裝常用的C++容器類型,如數(shù)組、arrary、vector、string等,用read(),write()函數(shù)來讀取緩沖區(qū)。
asio是一個(gè)相當(dāng)復(fù)雜的庫,本書只涉及其中的基本概念,還有許多異步IO相關(guān)的概念,在此不一一介紹。

定時(shí)器

定時(shí)器是asio庫里最簡單的一個(gè)IO模型示范,提供等待時(shí)間終止的功能,通過它我們可以快速熟悉asio的基本使用方法。?

?

#include <iostream> #include <conio.h> using namespace std; #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> using namespace boost; using namespace boost::asio; //同步定時(shí)器 void test1() {io_service ios;//所有的asio程序必須要有一個(gè)io_service對象deadline_timer t(ios,boost::posix_time::seconds(2));//兩秒鐘后定時(shí)器終止cout<<t.expires_at()<<endl;//查看終止的決定時(shí)間t.wait();//調(diào)用wait()同步等待cout<<"hello asio"<<endl; //可以把它與thread庫的sleep()函數(shù)對比研究一下,兩種雖然都是等待,但內(nèi)部機(jī)制完全不同:thread庫的sleep()使用了互斥量和條件變量,在線程中等待,而asio則是調(diào)用了操作系統(tǒng)的異步機(jī)制,如select,epool等完成。 //同步定時(shí)器的用法很簡單,但它演示了asio程序的基本結(jié)構(gòu)和流程:一個(gè)asio程序首先要定義一個(gè)io_service對象,它是前攝器模式中最重的proactor角色,然后我們聲明一個(gè)IO操作(這里是定時(shí)器),并把它掛接在io_service上,再然后就可以執(zhí)行后續(xù)的 同步或異步操作。 } //異步定時(shí)器:代碼大致與同步定時(shí)器相同,增加了回調(diào)函數(shù),并使用io_service_run()和定時(shí)器的async_wait() //首先我們要定義回調(diào)函數(shù),asio庫要求回調(diào)函數(shù)只能有一個(gè)參數(shù),而且這個(gè)參數(shù)必須是const asio::error_code&類型void myprint(boost::system::error_code ec) { cout<<"hello asio"<<endl; } void test2() {io_service ios;deadline_timer t(ios,boost::posix_time::seconds(3));t.async_wait(myprint);//異步等待,傳入回調(diào)函數(shù),立即返回cout<<"it show before t expired."<<endl;ios.run();//很重要,異步IO必須cout<<"runned"<<endl;//將與hello asio一起輸出,說明run()是阻塞函數(shù)//異步等待async_wait(),它通知io_service異步的執(zhí)行IO操作,并且注冊了回調(diào)哈思楠,用于在IO操作完成時(shí)有事件多路分離器分派返回值(error_code)調(diào)用。//最后我們必須調(diào)用io_service的run()成員函數(shù),它啟動(dòng)前攝器的事件處理循環(huán),阻塞等待所有的操作完成并分派事件。如果不調(diào)用run()那么雖然被異步執(zhí)行了,但沒有一個(gè)等待他完成的機(jī)制,回調(diào)函數(shù)將得不到執(zhí)行的機(jī)會(huì)。 } //下面我們實(shí)現(xiàn)一個(gè)可以定時(shí)執(zhí)行任意函數(shù)的定時(shí)器 a_timer(asyc timer),它持有一個(gè)asio定時(shí)器對象和一個(gè)計(jì)數(shù)器,還有一個(gè)function對象用來保存回調(diào)函數(shù) class a_timer { private:int count,cout_max; //計(jì)數(shù)器成員變量function<void()> f; //function對象,持有無參數(shù)無返回的可調(diào)用物deadline_timer t;//asio定時(shí)器 public://構(gòu)造函數(shù)初始化成員變量,將計(jì)數(shù)器清理,設(shè)置計(jì)數(shù)器的上限,拷貝存儲(chǔ)回調(diào)函數(shù),并立即啟動(dòng)定時(shí)器//之所以要"立即"啟動(dòng),是因?yàn)槲覀儽仨毎b在io_service.run()之前至少有一個(gè)異步操作在執(zhí)行,否則io_service.run()會(huì)因?yàn)闆]有事件處理而立即不等待返回。template<typename F>a_timer(io_service& ios,int x,F func):f(func),cout_max(x),count(0),t(ios,posix_time::microsec(500))//模板類型,可接受任意可調(diào)用物{t.async_wait(bind(&a_timer::call_func,this,placeholders::error));//命名空間下asio::placeholders的一個(gè)占位符error,他的作用類似于bind庫的占位符_1,_2,用于傳遞errror_code值。}//call_func()內(nèi)部累加計(jì)數(shù)器,如果計(jì)數(shù)器未達(dá)到上限則調(diào)用function對象f,然后重新設(shè)置定時(shí)器的終止時(shí)間,再次異步等待被調(diào)用,從而達(dá)到反復(fù)執(zhí)行的目的。void call_func(const boost::system::error_code &){if(count >= cout_max){return;}++count;f();t.expires_at(t.expires_at()+posix_time::millisec(500));//設(shè)置定時(shí)器的終止時(shí)間為0.5秒之后t.async_wait(bind(&a_timer::call_func,this,placeholders::error));} }; void print1(int index) {cout<<"hello asio:"<<index<<endl; } void print2() {cout<<"hello boost"<<endl; } void test3() {io_service ios; a_timer a(ios,10,bind(print1,2));//啟用第一個(gè)定時(shí)器a_timer at(ios,5,print2);//啟用第二個(gè)定時(shí)器ios.run();//ios等待異步調(diào)用結(jié)束 } //查詢網(wǎng)絡(luò)地址 /*之前關(guān)于TCP通信的所有論述我們都是使用直接的IP地址,但在實(shí)際生活中大多數(shù)時(shí)候我們不可能知道socket連接另一端的地址,而只有一個(gè)域名,這時(shí)候我們就需要使用resolver類來通過域名獲得可用的IP,它可用實(shí)現(xiàn)與IP版本無關(guān)的網(wǎng)址解析。 resolver使用內(nèi)部類query和iterator共同完成查詢IP地址的工作:首先使用網(wǎng)址和服務(wù)器名創(chuàng)建query對象,然后由resolver()函數(shù)生產(chǎn)iterator對象,它代表了查詢到的ip端點(diǎn)。之后就可以使用socket對象嘗試連接,直到找到一個(gè)可用的為止。 */ #include <boost/lexical_cast.hpp> void resolv_connect(ip::tcp::socket &sock,const char* website ,int port)//使用此函數(shù)來封裝resolver的調(diào)用過程 {ip::tcp::resolver rlv(sock.get_io_service());//resolver對象ip::tcp::resolver::query qry(website,lexical_cast<string>(port));//創(chuàng)建一個(gè)query對象;query只接受字符串參數(shù)ip::tcp::resolver::iterator iter=rlv.resolve(qry);ip::tcp::resolver::iterator end;//逾尾迭代器system::error_code ec=error::host_not_found;for (; ec && iter != end;++iter){sock.close();sock.connect(*iter,ec);//嘗試連接端點(diǎn)}if (ec)//只有當(dāng)ec為0時(shí),才會(huì)連接成功{cout<<"can't connect."<<endl;throw system::system_error(ec);}cout<<"connect success."<<endl; } void test4() {try{io_service ios;ip::tcp::socket sock(ios);resolv_connect(sock,"www.boost.org",80);//其他操作ios.run();} catch (std::exception& e){cout<<e.what()<<endl;} } void test(char t) { std::cout<<"press key====="<<t<<std::endl; switch (t) { case '1':test1();break; case '2':test2();break; case '3':test3();break; case '4':test4();break; case 27: case 'q':exit(0);break; default: std::cout<<"default "<<t<<std::endl;break; } } void main() { while(1) test(getch()); }

?


?

轉(zhuǎn)載于:https://www.cnblogs.com/pangblog/p/3290178.html

總結(jié)

以上是生活随笔為你收集整理的[Boost基础]并发编程——asio网络库——定时器deadline_timer的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。