#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
