In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article is about an example analysis based on the threadpool thread pool in Clover 11. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Clippers 11 added thread libraries, leaving the history that standard libraries do not support concurrency. However, C++ 's support for multithreading is still relatively low, and slightly more advanced uses need to be implemented on their own, such as thread pools, semaphores, and so on. Thread pool (thread pool) is asked many times in interviews, and the general answer is: "manage a task queue, a thread queue, and then assign one task to one thread at a time, over and over again." There seems to be no problem. But something went wrong when writing the program.
Code implementation
# pragma once#ifndef THREAD_POOL_H#define THREAD_POOL_H#include # include namespace std {# define MAX_THREAD_NUM 256 / thread pool, you can submit variable parameter functions or anonymous functions of Ramda expressions for execution, and you can obtain the execution return values / / do not support class member functions, support class static member functions or global functions, Opteron () functions and other class threadpool {using Task = std::function / / Thread Pool std::vector pool; / / Task queue std::queue tasks; / / synchronous std::mutex mlockout; / / conditional blocking std::condition_variable cv_task; / / whether to close submission std::atomic stoped; / / number of idle threads std::atomic idlThrNum;public: inline threadpool (unsigned short size = 4): stoped {false} {idlThrNum = size
< 1 ? 1 : size; for (size = 0; size < idlThrNum; ++size) { //初始化线程数量 pool.emplace_back( [this] { // 工作线程函数 while(!this->Stoped) {std::function task; {/ / get a task std::unique_lock lock {this- > m_lock} to be executed / / the advantage of unique_lock over lock_guard is that unlock () and lock () this- > cv_task.wait at any time (lock, [this] {return this- > stoped.load () | |! this- > tasks.empty ();}) / / wait until there is task if (this- > stoped & & this- > tasks.empty ()) return; task = std::move (this- > tasks.front ()); / / take a task this- > tasks.pop ();} idlThrNum--; task (); idlThrNum++ }});} inline ~ threadpool () {stoped.store (true); cv_task.notify_all (); / / Wake up all threads to execute for (std::thread& thread: pool) {/ / thread.detach (); / / Let threads "fend for themselves" if (thread.joinable ()) thread.join () / / wait for the task to finish. Premise: the thread must finish executing}} public: / / submit a task / / call .get () to get the return value and wait for the task to be executed. / / there are two ways to call class members. / / one is to use bind: .commit (& Dog::sayHello, & dog). / / one is to use mem_fn: .commit (std::mem_fn (& Dog::sayHello), & dog) template auto commit (Fair& f, Args&&...) Args)-> std::future {if (stoped.load ()) / / stop = = true? Throw std::runtime_error ("commit on ThreadPool is stopped."); using RetType = decltype (f (args...)); / / typename std::result_of::type, the return type of function f is auto task = std::make_shared (std::bind (std::forward (f), std::forward (args)...)); / / wtf! Std::future future = task- > get_future (); {/ / add tasks to queue std::lock_guard lock {m_lock}; / / A pair of statement locks for the current block lock_guard is the stack wrapper class of mutex, lock () when constructing, and unlock () tasks.emplace ([task] () {/ / push (Task {...}) (* task) () });} cv_task.notify_one (); / / Wake up a thread to execute return future;} / / number of idle threads int idlCount () {return idlThrNum;}};} # endif
Not much code, hundreds of lines of code to complete the thread pool, and, look at commit, ha, is not a fixed parameter, no parameter limit! This benefits from variable parameter templates.
How do I use it?
Look at the following code (expand to see)
# include "threadpool.h" # include void fun1 (int slp) {printf ("hello, fun1!% d\ n", std::this_thread::get_id ()); if (slp > 0) {printf ("= fun1 sleep% d =% d\ n", slp, std::this_thread::get_id ()); std::this_thread::sleep_for (std::chrono::milliseconds (slp)) }} struct gfun {int operator () (int n) {printf ("% d hello, gfun!% d\ n", n, std::this_thread::get_id ()); return 42;}}; class A {public: static int Afun (int n = 0) {/ / function must be static to directly use thread pool std::cout
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.