当前位置:网站首页>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 .
边栏推荐
- Class exercises
- [combinatorics] generating function (positive integer splitting | unordered | ordered | allowed repetition | not allowed repetition | unordered not repeated splitting | unordered repeated splitting)
- Sepconv (separable revolution) code recurrence
- Closure and closure function
- [combinatorics] generating function (example of generating function | calculating generating function with given general term formula | calculating general term formula with given generating function)
- Three gradient descent methods and code implementation
- 2022-2028 global plasmid DNA cdmo industry research and trend analysis report
- Lesson 13 of the Blue Bridge Cup -- tree array and line segment tree [exercise]
- Redis on local access server
- 多媒体NFT聚合平台OKALEIDO即将上线,全新的NFT时代或将来临
猜你喜欢
G1 garbage collector of garbage collector
After the festival, a large number of people change careers. Is it still time to be 30? Listen to the experience of the past people
Redis core technology and practice - learning notes (VII) sentinel mechanism
How to quickly view the inheritance methods of existing models in torchvision?
2022-2028 global solid phase extraction column industry research and trend analysis report
Opencv learning notes (continuously updated)
Multifunctional web file manager filestash
Grammaire anglaise Nom - Classification
Administrative division code acquisition
Computer graduation design PHP campus address book telephone number inquiry system
随机推荐
Typescript official website tutorial
Module 9 operation
PHP MySQL preprocessing statement
Install apache+php+mysql+phpmyadmin xampp and its error resolution
What London Silver Trading software supports multiple languages
网格图中递增路径的数目[dfs逆向路径+记忆dfs]
Reappearance of ASPP (atlas spatial pyramid pooling) code
English grammar_ Adjective / adverb Level 3 - multiple expression
Change the single node of Postgres database into master-slave
042. (2.11) do it when it's time to do it
Prototype inheritance..
[linux]centos 7 reports an error when installing MySQL "no package MySQL server available" no package ZABBIX server MySQL available
Computer graduation design PHP campus address book telephone number inquiry system
Valentine's day, send you a little red flower~
What problems can cross-border e-commerce sellers solve with multi platform ERP management system
A. Berland Poker & 1000 [simple mathematical thinking]
2022-2028 global sepsis treatment drug industry research and trend analysis report
How do microservices aggregate API documents? This wave of operation is too good
199. Right view of binary tree - breadth search
Enterprise custom form engine solution (12) -- form rule engine 2