当前位置:网站首页>Boost. Asio Library
Boost. Asio Library
2022-07-03 18:33:00 【It's haohaozi】
1. io_service
io_service
yes Boost::Asio The core object in the namespace ,I/O service Is a channel for accessing operating system resources , And submit I/O Requested procedure and execution I/O Establish communication between the requested operating systems .io_service The most frequently used method for objects is run()
, It is used for continuous response io_service Object needs to handle events . So it will block , Until all the events are handled .
If you want to let io_service
Object when there is no event to handle ,run()
Still blocked , have access to work()
Method . for example :
#include <boost/asio.hpp>
#include <iostream>
int main(void) {
boost::asio::io_service io_svc;
boost::asio::io_service::work worker(io_svc); // Equivalent to changing io_svc The nature of
io_svc.run(); // This waiting does not occupy CPU resources
std::cout << "We will not see this line in console window :(" << std::endl;
return 0;
}
In the code above ,work
Class notification io_service
Object it has work to do , But we don't define what work is . therefore , The program will be infinitely blocked , So the last line of code will not output . The reason for the blockage is run() Function called .
And run()
The opposite is poll()
Method .poll()
Method is used to handle ready programs , Until there are no remaining ready programs or until io_service Object stop . however , And run() Compared to the function ,poll() Functions do not block programs , Even if work()
Method .
2. Delete work object
You can do this by io_service
Object to unblock the program , But in order to remove the working object itself , We must use a pointer to the working object .
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include<boost/chrono.hpp>
#include <iostream>
int main(void) {
boost::asio::io_service io_svc;
boost::shared_ptr<boost::asio::io_service::work> worker(
new boost::asio::io_service::work(io_svc));
worker.reset(); // Destroy the pointer , All pending work will be over
io_svc.run();
std::cout << "We will not see this line in console window :(" << std::endl;
return 0;
}
3. Dealing with multithreading
One io_service
Process in multiple threads .
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <iostream>
boost::asio::io_service io_svc;
int a = 0;
void WorkerThread() {
std::cout << ++a << ".\n";
io_svc.run();
std::cout << "End.\n";
}
int main(void) {
boost::shared_ptr<boost::asio::io_service::work> worker(
new boost::asio::io_service::work(io_svc));
std::cout << "Press ENTER key to exit!" << std::endl;
boost::thread_group threads;
for(int i=0; i<5; i++)
threads.create_thread(WorkerThread);
std::cin.get();
io_svc.stop(); // worker.reset();
threads.join_all();
return 0;
}
4. Copy io_service The pointer
Other things to note are io_service
Is an object that cannot be copied . But it can be done by shared_ptr Instantiate in pointer io_service object , Make it replicable , So we can bind it to worker thread()
In the method , Use as a thread handler .
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace boost::asio;
void workThread(std::shared_ptr<io_service> iosvc, int counter) {
std::cout << counter << std::endl;
iosvc->run();
std::cout << "End." << std::endl;
}
int main() {
//io_service ios;
auto io_svc = std::make_shared<io_service>();
std::shared_ptr<io_service::work> worker(new io_service::work(*io_svc));
std::cout << "Press ENTER key to exit!" << std::endl;
boost::thread_group threads;
for(int i=1; i<=5; i++) {
threads.create_thread(boost::bind(&workThread, io_svc, i));
}
std::cin.get();
worker.reset(); // io_svc->stop(); Is to stop all work , Even if you haven't finished .worker.reset(); Like Cancel io_service Object's work attribute
threads.join_all();
return 0;
}
5. The mutex
In the above examples of multithreading , The operation is random . because std::cout Object is a global object , Write from different threads at once , It may cause output formatting problems . Mutexes can be used to synchronize access to any global or shared data .
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
boost::mutex global_stream_lock;
void WorkerThread(boost::shared_ptr<boost::asio::io_service> iosvc,
int counter) {
global_stream_lock.lock();
std::cout << counter << ".\n";
global_stream_lock.unlock();
iosvc->run();
global_stream_lock.lock();
std::cout << "End.\n";
global_stream_lock.unlock();
}
int main(void) {
boost::shared_ptr<boost::asio::io_service> io_svc(
new boost::asio::io_service
);
boost::shared_ptr<boost::asio::io_service::work> worker(
new boost::asio::io_service::work(*io_svc)
);
std::cout << "Press ENTER key to exit!" << std::endl;
boost::thread_group threads;
for(int i=1; i<=5; i++)
threads.create_thread(boost::bind(&WorkerThread, io_svc, i));
std::cin.get();
io_svc->stop();
threads.join_all();
return 0;
}
6. towards I/O service Distribution work
stay io_service
There are two ways to io_service
Assigned tasks :post()
Method for request io_service
Object runs after we queue all the work io_service
The object corresponds to work, So it doesn't allow us to run work immediately . and dispatch()
The method is also used to io_service
Object makes a request to run io_service
Object's work , But it will execute the work immediately , Instead of queuing up .
post()
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
boost::mutex global_stream_lock;
void WorkerThread(boost::shared_ptr<boost::asio::io_service> iosvc,
int counter) {
global_stream_lock.lock();
std::cout << counter << ".\n";
global_stream_lock.unlock();
iosvc->run();
global_stream_lock.lock();
std::cout << "End.\n";
global_stream_lock.unlock();
}
size_t fac(size_t n) {
if ( n <= 1 ) {
return n;
}
boost::this_thread::sleep(
boost::posix_time::milliseconds(1000)
);
return n * fac(n - 1);
}
void CalculateFactorial(size_t n) {
global_stream_lock.lock();
std::cout << "Calculating " << n << "! factorial" << std::endl;
global_stream_lock.unlock();
size_t f = fac(n);
global_stream_lock.lock();
std::cout << n << "! = " << f << std::endl;
global_stream_lock.unlock();
}
int main(void) {
boost::shared_ptr<boost::asio::io_service> io_svc(
new boost::asio::io_service
);
boost::shared_ptr<boost::asio::io_service::work> worker(
new boost::asio::io_service::work(*io_svc)
);
global_stream_lock.lock();
std::cout << "The program will exit once all work has finished." << std::endl;
global_stream_lock.unlock();
boost::thread_group threads;
for(int i=1; i<=5; i++)
threads.create_thread(boost::bind(&WorkerThread, io_svc, i));
io_svc->post(boost::bind(CalculateFactorial, 5));
io_svc->post(boost::bind(CalculateFactorial, 6));
io_svc->post(boost::bind(CalculateFactorial, 7));
worker.reset();
threads.join_all();
return 0;
}
stay main Function , Use post() Function publishes three function objects to io_service On the object . We're initializing 5 A worker thread will io_service The object pointer is assigned to 5 In threads . such , Because we call in every thread io_service Object's run() function , therefore io_service Object's work Will run post() Method release work .
dispatch()
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace boost::asio;
//boost::mutex global_lock;
void Dispatch(int i) {
std::cout << "dispatch() function for i=" << i << std::endl;
}
void Post(int i) {
std::cout << "post() function for i=" << i << std::endl;
}
void workerThread(std::shared_ptr<io_service> iosv) {
std::cout << "Thread Start." <<std::endl;
iosv->run();
std::cout << "Thread Finish." << std::endl;
}
void running(std::shared_ptr<io_service> iosv) {
for(int i=0; i<5; i++) {
iosv->dispatch(boost::bind(&Dispatch, i));
iosv->post(boost::bind(&Post, i));
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
}
int main() {
auto iosv =std::make_shared<io_service>();
//io_service::work worker(*iosv);
auto worker = std::make_shared<io_service::work>(*iosv); // make_shared<io_service::work> Would call work Constructor for
boost::thread_group threads;
threads.create_thread(boost::bind(&workerThread, iosv));
iosv->post(boost::bind(&running, iosv));
worker.reset();
threads.join_all();
return 0;
}
Output results :
Thread Start.
dispatch() function for i=0
dispatch() function for i=1
dispatch() function for i=2
dispatch() function for i=3
dispatch() function for i=4
post() function for i=0
post() function for i=1
post() function for i=2
post() function for i=3
post() function for i=4
Thread Finish.
According to the conventional understanding, the output result should be dispatch() and post() Alternate execution , But the result is to execute first dispatch() Re execution post(). This is because dispatch() The distributed work requires immediate invocation from the current worker thread , and post() You must wait until the worker thread's handler completes before it can be called . let me put it another way ,post() Queue up when the worker thread has other pending events , It can't be allowed to execute until the handler finishes executing .
That is to say, we first post One. running Work , And in this job , also dispatch and post Work , that workerThread Process first in the same thread running Work , When running to dispatch when , although running The work is not finished , however dispatch It also requires immediate operation , and post Just put your tasks in a queue , When the thread is not busy, it can run , Wait in line when busy .
边栏推荐
- Torch learning notes (5) -- autograd
- 企业级自定义表单引擎解决方案(十二)--表单规则引擎2
- Postfix tips and troubleshooting commands
- English語法_名詞 - 分類
- Summary and Reflection on the third week of winter vacation
- [combinatorics] generating function (use generating function to solve the combination number of multiple sets R)
- Coordinate layer conversion tool (video)
- Real time split network (continuous update)
- Redis on local access server
- The second largest gay dating website in the world was exposed, and the status of programmers in 2022
猜你喜欢
Win32: dump file analysis of heap corruption
What problems can cross-border e-commerce sellers solve with multi platform ERP management system
AcWing 271. 杨老师的照相排列【多维DP】
Why can deeplab v3+ be a God? (the explanation of the paper includes super detailed notes + Chinese English comparison + pictures)
Codeforces Round #803 (Div. 2) C. 3SUM Closure
Multifunctional web file manager filestash
2022-2028 global physiotherapy clinic industry research and trend analysis report
English grammar_ Adjective / adverb Level 3 - multiple expression
PHP MySQL inserts multiple pieces of data
4. Load balancing and dynamic static separation
随机推荐
CTO and programmer were both sentenced for losing control of the crawler
[combinatorics] generating function (use generating function to solve the combination number of multiple sets R)
Win32: dump file analysis of heap corruption
Summary and Reflection on the third week of winter vacation
Theoretical description of linear equations and summary of methods for solving linear equations by eigen
Graduation summary
Supervisor monitors gearman tasks
Should I be laid off at the age of 40? IBM is suspected of age discrimination, calling its old employees "dinosaurs" and planning to dismiss, but the employees can't refute it
[combinatorics] generating function (use generating function to solve the number of solutions of indefinite equation example 2 | extended to integer solution)
网格图中递增路径的数目[dfs逆向路径+记忆dfs]
圖像24比特深度轉8比特深度
[combinatorics] generating function (property summary | important generating function)*
Golang string (string) and byte array ([]byte) are converted to each other
[combinatorics] generating function (use generating function to solve the number of solutions of indefinite equation)
[Godot] add menu button
【统信UOS】扫描仪设备管理驱动安装
Usage of laravel conditional array in
[combinatorics] generating function (positive integer splitting | repeated ordered splitting | non repeated ordered splitting | proof of the number of repeated ordered splitting schemes)
Administrative division code acquisition
Typescript official website tutorial