<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          #asio# Boost多線程與異步方案

          共 23625字,需瀏覽 48分鐘

           ·

          2024-12-05 17:36

          boost::asio::io_service

          Boost::asio::io_service
          io_service對(duì)象是boost asio框架中的調(diào)度器,所有異步io事件都是通過(guò)它來(lái)分發(fā)處理的

          io_service與線程的模式

          io_service與線程的模式
          1 一個(gè)io_service實(shí)例和一個(gè)處理線程的單線程
          當(dāng)幾個(gè)處理程序需要被同時(shí)調(diào)用時(shí),你通常會(huì)遇到瓶頸。如果一個(gè)處理程序需要花費(fèi)很長(zhǎng)的時(shí)間來(lái)執(zhí)行,所有隨后的處理程序都不得不等待。
          2 一個(gè)io_service實(shí)例和多個(gè)處理線程的多線程
          如果幾個(gè)處理程序被同時(shí)調(diào)用了,它們會(huì)在各自的線程里面被調(diào)用。唯一的瓶頸就是所有的處理線程都很忙的同時(shí)又有新的處理程序被調(diào)用。然而,這是有快速的解決方式的,增加處理線程的數(shù)目即可。
          3 多個(gè)io_service實(shí)例和多個(gè)處理線程的多線程
          當(dāng)你有成千上萬(wàn)實(shí)時(shí)(socket)連接時(shí)。你可以認(rèn)為每一個(gè)處理線程(運(yùn)行io_service::run()的線程)有它自己的select/epoll循環(huán);它等待任意一個(gè)socket連接,然后等待一個(gè)讀寫操作,當(dāng)它發(fā)現(xiàn)這種操作時(shí),就執(zhí)行。

          io_service調(diào)度器


          io_service 調(diào)度器
          io_service對(duì)象是asio框架中的調(diào)度器,所有異步io事件都是通過(guò)它來(lái)分發(fā)處理的
          io_service的作用: io_servie 實(shí)現(xiàn)了一個(gè)任務(wù)隊(duì)列,這里的任務(wù)就是void(void)的函數(shù)。Io_servie最常用的兩個(gè)接口是post和run,post向任務(wù)隊(duì)列中投遞任務(wù),run是執(zhí)行隊(duì)列中的任務(wù),直到全部執(zhí)行完畢,并且run可以被N個(gè)線程調(diào)用。Io_service是完全線程安全的隊(duì)列。
          1 post用于發(fā)布io事件,如timer,socket讀寫等,一般由asio框架相應(yīng)對(duì)象調(diào)用,無(wú)需我們顯式調(diào)用。
          2 run用于監(jiān)聽(tīng)io事件響應(yīng),并執(zhí)行響應(yīng)回調(diào),對(duì)于異步io操作需要在代碼中顯式調(diào)用,對(duì)于同步io操作則由io對(duì)象隱式調(diào)用(并不是run函數(shù),不過(guò)也是等待io事件)。

          同步模式

          同步模式
          在asio框架中,同步的io主要流程如下:  

          1 應(yīng)用程序調(diào)用IO對(duì)象成員函數(shù)執(zhí)行IO操作
          2 IO對(duì)象向io_service 提出請(qǐng)求.
          3 io_service 調(diào)用操作系統(tǒng)的功能執(zhí)行連接操作.
          4 操作系統(tǒng)向io_service 返回執(zhí)行結(jié)果.
          5 io_service將錯(cuò)誤的操作結(jié)果翻譯為boost::system::error_code類型,再傳遞給IO對(duì)象.
          6 如果操作失敗,IO對(duì)象拋出boost::system::system_error類型的異常.

          異步模式

          異步模式
          異步IO的處理流程則有些不同:  

          1 應(yīng)用程序調(diào)用IO對(duì)象成員函數(shù)執(zhí)行IO操作
          2 IO對(duì)象請(qǐng)求io_service的服務(wù)
          3 io_service 通知操作系統(tǒng)其需要開(kāi)始一個(gè)異步連接.
          4 操作系統(tǒng)指示連接操作完成, io_service從隊(duì)列中獲取操作結(jié)果
          5 應(yīng)用程序必須調(diào)用io_service::run()以便于接收結(jié)果
          6 調(diào)用io_service::run()后,io_service返回一個(gè)操作結(jié)果,并將其翻譯為error_code,傳遞到事件回調(diào)函數(shù)中

          io_service::post

          io_servie::Post方法
          Post向隊(duì)列中投遞任務(wù),然后激活空閑線程執(zhí)行任務(wù)。
          io_servie::run方法
          Run方法執(zhí)行隊(duì)列中的所有任務(wù),直到任務(wù)執(zhí)行完畢。
          Run方法的原則是:
          - 有任務(wù)立即執(zhí)行任務(wù),盡量使所有的線程一起執(zhí)行任務(wù)
          - 若沒(méi)有任務(wù),阻塞在epoll_wait上等待io事件
          - 若有新任務(wù)到來(lái),并且沒(méi)有空閑線程,那么先中斷epoll_wait,先執(zhí)行任務(wù)
          - 若隊(duì)列中有任務(wù),并且也需要epoll_wait監(jiān)聽(tīng)事件,那么非阻塞調(diào)用epoll_wait(timeout字段設(shè)置為0),待任務(wù)執(zhí)行完畢在阻塞在epoll_wait上。
          - 幾乎對(duì)線程的使用上達(dá)到了極致。
          - 從這個(gè)函數(shù)中可以知道,在使用ASIO時(shí),io_servie應(yīng)該盡量多,這樣可以使其epoll_wait占用的時(shí)間片最多,這樣可以最大限度的響應(yīng)IO事件,降低響應(yīng)時(shí)延。但是每個(gè)io_servie::run占用一個(gè)線程,所以io_servie最佳應(yīng)該和CPU的核數(shù)相同。
          io_servie::stop方法
          停止所有線程的任務(wù)

          學(xué)習(xí)案例

          io_service的機(jī)制
          1 run函數(shù)在io事件完成后會(huì)退出,導(dǎo)致后續(xù)基于該對(duì)象的異步io任務(wù)無(wú)法執(zhí)行
          給其【io_service】分配一個(gè)線程,然后執(zhí)行run函數(shù)。但run函數(shù)在io事件完成后會(huì)退出,線程會(huì)終止,后續(xù)基于該對(duì)象【io_service】的異步io任務(wù)無(wú)法得到調(diào)度。
          通過(guò)一個(gè)asio::io_service::work對(duì)象來(lái)守護(hù)io_service。這樣,即使所有io任務(wù)都執(zhí)行完成,也不會(huì)退出,繼續(xù)等待新的io任務(wù)。
           boost::asio::io_service io;
          boost::asio::io_service::work work(io);
          io.run();
          2. 回調(diào)在run函數(shù)的線程中同步執(zhí)行,當(dāng)回調(diào)處理時(shí)間較長(zhǎng)時(shí)阻塞后續(xù)io響應(yīng)
          解決這個(gè)問(wèn)題的方法有兩種:
          1. 啟動(dòng)多線程執(zhí)行run函數(shù)(run函數(shù)是線程安全的)
          2. 新啟動(dòng)一個(gè)線程(或通過(guò)線程池)來(lái)執(zhí)行回調(diào)函數(shù)。一般來(lái)講,如果回調(diào)處理事件不是特別短,應(yīng)該使用在線程池中處理回調(diào)的方式。
          3. 回調(diào)在run函數(shù)的線程中同步執(zhí)行,io事件較多的時(shí)候得不到及時(shí)響應(yīng)
          這個(gè)其實(shí)是性能問(wèn)題了,在多核cpu上可以通過(guò)在多個(gè)線程中執(zhí)行run函數(shù)來(lái)解決這一問(wèn)題。這種方式也只能充分利用cpu性能,本身性能問(wèn)題就不是光靠軟件就能解決的。

          學(xué)習(xí)案例

          學(xué)習(xí)范例:
          io_service 的使用框架
          #include <boost/asio.hpp>
          #include <boost/asio/io_service.hpp>
          #include <boost/thread.hpp>  
          #include <boost/atomic.hpp>  
          #include <boost/shared_ptr.hpp>  
          #include <boost/date_time/posix_time/ptime.hpp>  
          #include <boost/date_time.hpp>
          #include <iostream>

          int main()
          {
              //io_service asio框架的調(diào)度器,在多線程機(jī)制中提供任務(wù)隊(duì)列和任務(wù)分發(fā)功能
              boost::asio::io_service io_service;
              //work對(duì)象來(lái)守護(hù)io_service,即使所有io任務(wù)都執(zhí)行完成,也不會(huì)退出,繼續(xù)等待新的io任務(wù)。
              boost::asio::io_service::work work(io_service);
              //run用于監(jiān)聽(tīng)io事件響應(yīng),并執(zhí)行響應(yīng)回調(diào),1在io事件完成后退出 2io_service調(diào)用stop()后退出
              io_service.run();
              return 0;
          }

          鎖的機(jī)制
          #include <boost/thread.hpp>
          #include <boost/bind.hpp>
          #include <boost/thread/mutex.hpp>
          #include <iostream>
          long num = 0;
          //mutex 互斥量
          std::mutex num_mutex;
          void numplus() {
              std::cout << "++ :" << num << std::endl;
              //創(chuàng)建互斥量管理對(duì)象時(shí),它試圖給給定mutex加鎖。當(dāng)程序離開(kāi)互斥量管理對(duì)象的作用域時(shí),互斥量管理對(duì)象會(huì)析構(gòu)并且并釋放mutex。所以我們則不需要擔(dān)心程序跳出或產(chǎn)生異常引發(fā)的死鎖了。
              std::lock_guard<std::mutex> lock_guard(num_mutex);
              std::cout <<"++ before:" << num << std::endl;
              for (long i = 0; i < 1000000; ++i) {
                  num++;
              }
              std::cout << num << std::endl;
              std::cout << "++ after:" << num << std::endl;
          };
          void numsub() {
              std::cout << "-- :" << num << std::endl;
              std::lock_guard<std::mutex> lock_guard(num_mutex);
              std::cout << "-- before:" << num << std::endl;
              for (long i = 0; i < 1000000; ++i) {
                  num--;
              }
              std::cout << "-- after:" << num << std::endl;
          }
          int main() {
              std::thread t1(numplus);
              std::thread t2(numsub);
              t1.join();
              t2.join();
              std::cout << num << std::endl;
              system("PAUSE");
          }

          線程池管理
          #include <boost/thread.hpp>
          #include <boost/bind.hpp>
          #include <boost/thread/mutex.hpp>
          #include <iostream>
          void Run(int nVal)
          {
              //
              int nTemp = nVal * nVal;
              //下面輸出需要加鎖,不能多個(gè)線程共享輸出。
              static boost::mutex mutexCout;
              boost::lock_guard<boost::mutex> autoLock(mutexCout);
              std::cout << "thread Run: [" << nVal << "] " << nTemp << std::endl;
          }
          int main(int argc, char * argv[])
          {
              //定義一個(gè)線程組對(duì)象。提供了多個(gè)線程創(chuàng)建、保存、退出等管理。
              boost::thread_group threadGroup;
              //設(shè)置最大的線程個(gè)數(shù)。一般來(lái)說(shuō)是CPU的個(gè)數(shù)的兩倍是最高效率的線程模型。
              const int nMaxCount = 5;
              //循環(huán)地創(chuàng)建N個(gè)線程。
              for (int i = 0; i < nMaxCount; ++i)
              {
                  //使用create_thread函數(shù)可以創(chuàng)建多個(gè)線程,每個(gè)線程都調(diào)用函數(shù)Run運(yùn)行。
                  threadGroup.create_thread(boost::bind(Run, i));
              }
              //等所有線程退出。使用join_all函數(shù)來(lái)確保所有線程運(yùn)行,都從線程運(yùn)行函數(shù)里退出來(lái),如果其中一個(gè)線程沒(méi)有辦法退出,那么就會(huì)一直等待的。
              threadGroup.join_all();
              system("PAUSE");
              return 0;
          }

          多線程中使用io_service 使得線程一直運(yùn)行
          #include <boost/asio/io_service.hpp>
          #include <boost/thread/thread.hpp>
          #include <iostream>
          //asio 任務(wù)調(diào)度器
          boost::asio::io_service io_service;
          void WorkerThread()
          {
              std::cout << "Thread Start\n";
              //在多個(gè)線程中調(diào)用run()即可開(kāi)啟線程池,io_service負(fù)責(zé)執(zhí)行任務(wù)處理。阻塞在線程里
              io_service.run();
              std::cout << "Thread Finish\n";
          }
          int main(int argc, char * argv[])
          {
              //work類型的指針
              boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work(io_service));
              //輸出信息
              std::cout << "Press [return] to exit." << std::endl;
              //創(chuàng)建線程池/線程組
              boost::thread_group worker_threads;
              for (int x = 0; x < 4; ++x)
              {
                  //創(chuàng)建線程
                  worker_threads.create_thread(WorkerThread);
              }
              //主線程獲取監(jiān)聽(tīng)輸入
              std::cin.get();
              //stop()會(huì)告知io_service,所有的任務(wù)需要終止。它的調(diào)用可能會(huì)使已經(jīng)進(jìn)入隊(duì)列的任務(wù)得不到執(zhí)行。
              io_service.stop();
              //等所有線程退出。使用join_all函數(shù)來(lái)確保所有線程運(yùn)行,都從線程運(yùn)行函數(shù)里退出來(lái),如果其中一個(gè)線程沒(méi)有辦法退出,那么就會(huì)一直等待的。
              worker_threads.join_all();
              //屏幕暫停關(guān)閉
              system("PAUSE");
              return 0;
          }

          Bind的使用
          #include <boost/asio/io_service.hpp>
          #include <boost/thread/thread.hpp>
          #include <boost/bind.hpp>
          #include <iostream>
          //互斥量
          boost::mutex global_stream_lock;
          void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service)
          {
              //線程id
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl;
              global_stream_lock.unlock();
              //io_service阻塞
              io_service->run();
              //
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl;
              global_stream_lock.unlock();
          }
          int main(int argc, char * argv[])
          {
              //智能指針,維護(hù)對(duì)象,進(jìn)行自動(dòng)管理
              boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service);
              boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work(*io_service));
              //主線程 id
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Press [return] to exit." << std::endl;
              global_stream_lock.unlock();
              //多線程
              boost::thread_group worker_threads;
              for (int x = 0; x < 4; ++x)
              {
                  //使用boost::bind可以把函數(shù)調(diào)用包裝成為對(duì)象。便于傳遞參數(shù)
                  worker_threads.create_thread(boost::bind(&WorkerThread, io_service));
              }
              //主線程獲取鍵盤數(shù)據(jù)
              std::cin.get();
              //io_service關(guān)閉任務(wù)
              io_service->stop();
              //等所有線程退出。使用join_all函數(shù)來(lái)確保所有線程運(yùn)行,都從線程運(yùn)行函數(shù)里退出來(lái),如果其中一個(gè)線程沒(méi)有辦法退出,那么就會(huì)一直等待的。
              worker_threads.join_all();
              //屏幕暫停關(guān)閉
              system("PAUSE");
              return 0;
          }

          Post dispatch
          #include <boost/asio/io_service.hpp>
          #include <boost/thread/thread.hpp>
          #include <boost/bind.hpp>
          #include <iostream>
          boost::mutex global_stream_lock;
          void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service,int i)
          {
              std::cout << i << std::endl;
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl;
              global_stream_lock.unlock();
              io_service->run();
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl;
              global_stream_lock.unlock();
          }
          //dispatch會(huì)立即執(zhí)行任務(wù),否則把任務(wù)加入到queue
          void Dispatch(int x)
          {
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] " << __FUNCTION__ << " x = " << x << std::endl;
              global_stream_lock.unlock();
          }
          //post只會(huì)把任務(wù)加入到隊(duì)列
          void Post(int x)
          {
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] " << __FUNCTION__ << " x = " << x << std::endl;
              global_stream_lock.unlock();
          }
          void Run3(boost::shared_ptr< boost::asio::io_service > io_service)
          {
              for (int x = 0; x < 3; ++x)
              {
                  io_service->dispatch(boost::bind(&Dispatch, x * 2));
                  io_service->post(boost::bind(&Post, x * 2 + 1));
                  boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
              }
          }
          int main(int argc, char * argv[])
          {
              boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service);
              boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work(*io_service));
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] The program will exit when all  work has finished." << std::endl;
              global_stream_lock.unlock();
              boost::thread_group worker_threads;
              for (int x = 0; x < 1; ++x)
              {
                  worker_threads.create_thread(boost::bind(&WorkerThread, io_service, x));
              }
              io_service->post(boost::bind(&Run3, io_service));
              //立即結(jié)束任務(wù)
              work.reset();
              worker_threads.join_all();
              //屏幕暫停關(guān)閉
              system("PAUSE");
              return 0;
          }

          Strand 順序處理
          #include <boost/asio/io_service.hpp>
          #include <boost/thread/thread.hpp>
          #include <boost/bind.hpp>
          #include <boost/asio/strand.hpp>
          #include <iostream>
          boost::mutex global_stream_lock;
          void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service)
          {
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Start" << std::endl;
              global_stream_lock.unlock();
              io_service->run();
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] Thread Finish" << std::endl;
              global_stream_lock.unlock();
          }
          void PrintNum(int x)
          {
              std::cout << "[" << boost::this_thread::get_id() << "] x: " << x << std::endl;
          }
          int main(int argc, char * argv[])
          {
              boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service);
              boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work(*io_service));
              //strand提供順序化的事件執(zhí)行器。意思是,如果以“work1->work2->work3”的順序post,不管有多少個(gè)工作線程,它們依然會(huì)以這樣的順序執(zhí)行任務(wù)。
              boost::asio::io_service::strand strand(*io_service);
              global_stream_lock.lock();
              std::cout << "[" << boost::this_thread::get_id() << "] The program will exit when all  work has finished." << std::endl;
              global_stream_lock.unlock();
              boost::thread_group worker_threads;
              for (int x = 0; x < 2; ++x)
              {
                  worker_threads.create_thread(boost::bind(&WorkerThread, io_service));
              }
              boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
              //strand.post( boost::bind( &PrintNum, 1 ) );
              //strand.post( boost::bind( &PrintNum, 2 ) );
              //strand.post( boost::bind( &PrintNum, 3 ) );
              //strand.post( boost::bind( &PrintNum, 4 ) );
              //strand.post( boost::bind( &PrintNum, 5 ) );
              io_service->post(boost::bind(&PrintNum, 1));
              io_service->post(boost::bind(&PrintNum, 2));
              io_service->post(boost::bind(&PrintNum, 3));
              io_service->post(boost::bind(&PrintNum, 4));
              io_service->post(boost::bind(&PrintNum, 5));
              work.reset();
              worker_threads.join_all();
              return 0;
          }

          boost::noncopyable
          #include <iostream>
          #include <boost/noncopyable.hpp>
          class Test1 {
          public:
              Test1(int i) { std::cout << "This is Test1 that is copyable" << std::endl; }
          };
          //將私有化類的拷貝構(gòu)造函數(shù)和拷貝賦值操作符,這樣子類可以調(diào)用,但是外部調(diào)用者不能通過(guò)復(fù)制/賦值等語(yǔ)句來(lái)產(chǎn)生一個(gè)新的對(duì)象。不支持使用復(fù)制的方式來(lái)實(shí)例化類。
          class Test2 : boost::noncopyable {
          public:
              Test2(int i) { std::cout << "This is Test2 that is noncopyable" << std::endl; }
          };
          int main()
          {
              Test1 t1(1);
              Test2 t2(2);
              Test1 t3 = t1;    // It's OK
              Test1 t4(t1);     // It's OK
              
              Test2 t5 = t2;    // Cannot be referenced
              Test2 t6(t2);     // Cannot be referenced
              Test2 &t7 = t2;   // It's OK
              return 0;
          }

          boost::asio::deadline_timer 計(jì)時(shí)器 同步模式
          #include <iostream>
          #include <boost/asio.hpp>
          #include <boost/date_time/posix_time/posix_time.hpp>
          int main()
          {
              //創(chuàng)建任務(wù)調(diào)度器 io_service
              boost::asio::io_service io;
              //定時(shí)器
              boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
              //阻塞等待,boost::asio::deadline_timer::wait()的在創(chuàng)建后5秒內(nèi)(注意:不是等待開(kāi)始后),timer到時(shí)之前不會(huì)返回任何值.
              t.wait();
              //boost::asio::deadline_timer::wait()在到時(shí)的timer對(duì)象上調(diào)用,會(huì)立即return,輸出信息
              std::cout << "Hello, world! ";
              return 0;
          }

          boost::asio::deadline_timer 計(jì)時(shí)器 異步模式
          #include <iostream>  
          #include <boost/asio.hpp>

          void handler(const boost::system::error_code &ec)
          {
              std::cout << "5 s." << std::endl;
          }
          int main()
          {
              boost::asio::io_service io_service;
              boost::asio::io_service::work work(io_service);
              boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(5));
              timer.async_wait(handler);
              std::cout << "soon." << std::endl;
              io_service.run();
          }

          多線程執(zhí)行任務(wù):一個(gè)io_service多個(gè)thread
          #include <boost/asio.hpp>
          #include <boost/thread.hpp>
          #include <iostream>
          void handler1(const boost::system::error_code &ec)
          {
              for (int i = 0; i < 10000; i++)
              {
                  std::cout << "1." << std::endl;
              }
          }
          void handler2(const boost::system::error_code &ec)
          {
              for (int i = 0; i < 10000; i++)
              {
                  std::cout << "2." << std::endl;
              }
          }
          boost::asio::io_service io_service;
          void run()
          {
              io_service.run();
          }
          int main()
          {
              boost::asio::deadline_timer timer1(io_service, boost::posix_time::seconds(5));
              timer1.async_wait(handler1);
              boost::asio::deadline_timer timer2(io_service, boost::posix_time::seconds(5));
              timer2.async_wait(handler2);
              boost::thread thread1(run);
              boost::thread thread2(run);
              thread1.join();
              thread2.join();
          }
          在 main() 中創(chuàng)建了兩個(gè)線程。這兩個(gè)線程均針對(duì)同一個(gè) I/O 服務(wù)調(diào)用了 run() 方法。這樣當(dāng)異步操作完成時(shí),這個(gè) I/O 服務(wù)就可以使用兩個(gè)線程去執(zhí)行句柄函數(shù)。
          兩個(gè)計(jì)時(shí)數(shù)均被設(shè)為在五秒后觸發(fā)。由于有兩個(gè)線程,所以 handler1() 和 handler2() 可以同時(shí)執(zhí)行。如果第二個(gè)計(jì)時(shí)器觸發(fā)時(shí)第一個(gè)仍在執(zhí)行,則第二個(gè)句柄就會(huì)在第二個(gè)線程中執(zhí)行。如果第一個(gè)計(jì)時(shí)器的句柄已經(jīng)終止,則 I/O 服務(wù)可以自由選擇任一線程。
          線程可以提高應(yīng)用程序的性能。因?yàn)榫€程是在處理器內(nèi)核上執(zhí)行的,所以創(chuàng)建比內(nèi)核數(shù)更多的線程是沒(méi)有意義的。這樣可以確保每個(gè)線程在其自己的內(nèi)核上執(zhí)行,而沒(méi)有同一內(nèi)核上的其它線程與之競(jìng)爭(zhēng)。

          多個(gè)io_service多個(gè)thread
          多次調(diào)用同一個(gè) I/O 服務(wù)的 run() 方法,是為基于 Boost.Asio 的應(yīng)用程序增加可擴(kuò)展性的推薦方法。另外還有一個(gè)不同的方法:不要綁定多個(gè)線程到單個(gè) I/O 服務(wù),而是創(chuàng)建多個(gè) I/O 服務(wù)。然后每一個(gè) I/O 服務(wù)使用一個(gè)線程。如果 I/O 服務(wù)的數(shù)量與系統(tǒng)的處理器內(nèi)核數(shù)量相匹配,則異步操作都可以在各自的內(nèi)核上執(zhí)行。
          #include <boost/asio.hpp>
          #include <boost/thread.hpp>
          #include <iostream>
          void handler1(const boost::system::error_code &ec)
          {
              for (int i = 0; i < 10000; i++)
              {
                  std::cout << "1." << std::endl;
              }
          }
          void handler2(const boost::system::error_code &ec)
          {
              for (int i = 0; i < 10000; i++)
              {
                  std::cout << "2." << std::endl;
              }
          }
          boost::asio::io_service io_service1;
          boost::asio::io_service io_service2;
          void run1()
          {
              io_service1.run();
          }
          void run2()
          {
              io_service2.run();
          }
          int main()
          {
              boost::asio::deadline_timer timer1(io_service1, boost::posix_time::seconds(5));
              timer1.async_wait(handler1);
              boost::asio::deadline_timer timer2(io_service2, boost::posix_time::seconds(5));
              timer2.async_wait(handler2);
              boost::thread thread1(run1);
              boost::thread thread2(run2);
              thread1.join();
              thread2.join();
          }

          #include <boost/thread.hpp>
          #include <boost/bind.hpp>
          #include <boost/asio.hpp>
          #include <iostream>
          using namespace boost::asio;
          io_service service;
          void func(int i) {
              std::cout << "func called, i= " << i << std::endl;
          }
          void worker_thread() {
              service.run();
          }
          int main(int argc, char* argv[]) {
              for (int i = 0; i < 10; ++i)
                  service.post(boost::bind(func, i));
              boost::thread_group threads;
              for (int i = 0; i < 3; ++i)
                  threads.create_thread(worker_thread);
              // wait for all threads to be created
              boost::this_thread::sleep(boost::posix_time::millisec(500));
              threads.join_all();
              getchar();
          }

          循環(huán)計(jì)時(shí)器
          #include <iostream>
          #include <boost/asio.hpp>
          #include <boost/bind.hpp>
          #include <boost/date_time/posix_time/posix_time.hpp>
          void print(const boost::system::error_code& /*e*/,
              boost::asio::deadline_timer* t, int* count)
          {
              if (*count < 5)
              {
                  std::cout << *count << std::endl;
              }
              ++(*count);
              std::cout << *count << std::endl;
              //在計(jì)時(shí)器處理程序中調(diào)用deadline_timer :: expires_from_now和deadline_timer :: async_wait來(lái)執(zhí)行此操作,這將在最后一個(gè)計(jì)時(shí)器到期時(shí)添加計(jì)時(shí)器
              t->expires_at(t->expires_at() + boost::posix_time::seconds(5));
              t->async_wait(boost::bind(print,
                  boost::asio::placeholders::error, t, count));
          }
          int main()
          {
              boost::asio::io_service io;
              int count = 0;
              boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
              t.async_wait(boost::bind(print,
                  boost::asio::placeholders::error, &t, &count));
              io.run();
              std::cout << "Final count is " << count << std::endl;
              return 0;
          }

          參考資料

          參考資料
          https://www.cnblogs.com/fnlingnzb-learner/p/10402232.html
          https://blog.csdn.net/qq_38365116/article/details/85102103
          https://blog.csdn.net/guotianqing/article/details/100730340
          boost::thread_group join_all
          https://blog.csdn.net/caimouse/article/details/8741295
          互斥量、鎖
          https://www.cnblogs.com/flyinggod/p/13570390.html
          io_service 多線程,一個(gè)線程綁定一個(gè)函數(shù)
          https://blog.csdn.net/guotianqing/article/details/100730340
          boost::noncopyable
          https://blog.csdn.net/rangfei/article/details/122464346
          boost::asio::io_service post run stop reset work
          https://www.cnblogs.com/fnlingnzb-learner/p/10402232.html
          io_service 與多線程的模式
          https://blog.csdn.net/qq_38365116/article/details/85102103
          boost::asio::io_service創(chuàng)建線程池簡(jiǎn)單實(shí)例
          https://blog.csdn.net/guotianqing/article/details/100730340
          boost::asio 網(wǎng)絡(luò)編程
          https://blog.csdn.net/smilejiasmile/article/details/114330843
          boost asio 重復(fù)計(jì)時(shí)器
          https://www.icode9.com/content-4-494864.html
          boost 多線程使用
          https://blog.csdn.net/alppkk4545/article/details/101575899
          https://www.cnblogs.com/ttmoon/p/7658224.html
          https://www.codenong.com/22826143/
          https://www.codenong.com/61276549/
          https://blog.csdn.net/zzhongcy/article/details/85162856
          std thread join 等待線程執(zhí)行返回
          https://blog.csdn.net/duan19920101/article/details/121357347

          瀏覽 95
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成年人视频免费在线观看大香蕉 | 99re视频在线 | 在线日韩一区二区 | 福利视频三区 | 玉米地一级婬片A片 |