当前位置:网站首页>Multithreaded application (thread pool, singleton mode)
Multithreaded application (thread pool, singleton mode)
2022-07-07 11:07:00 【Exy-】
Thread pool
A bunch of threads handle tasks , It is mainly aimed at scenarios that need to be handled by a large number of tasks , Using multiple execution streams can improve processing efficiency
If a task arrives, create a thread to handle it, which has great disadvantages :
- cost : Total time = Thread creation time + Task processing time + Thread destruction time , If the task processing time is short , Then a lot of time is consumed by thread creation and destruction
- risk : If a large number of threads come in , The system may collapse under peak pressure
thought : Thread pool is actually a pile of created threads and a task queue , When a task comes, it is thrown into the thread pool , Allocate a thread to process
There is a maximum number of threads and task nodes in the thread pool , Avoid resource consumption .
Realization :
typedef void (*handler_t)(int data);
class ThreadTask{
private:
int _data;// Data to process
handler_t _handler;// Functions that process data
public:
ThreadTask() {}
ThreadTask(int data, handler_t handler):_data(data),
_handler(handler){}
void Run(){
_handler(_data);
}
};
class BlockQueue
{
private:
std::queue<ThreadTask> _queue;
int _capacity;
pthread_mutex_t _mutex;
pthread_cond_t _cond_pro;
pthread_cond_t _cond_con;
public:
BlockQueue(int maxq = MAXQ):_capacity(maxq){
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_cond_pro, NULL);
pthread_cond_init(&_cond_con, NULL);
}
~BlockQueue() {
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond_pro);
pthread_cond_destroy(&_cond_con);
}
bool Push(const ThreadTask &data){
pthread_mutex_lock(&_mutex);
while(_queue.size() == _capacity) {
pthread_cond_wait(&_cond_pro, &_mutex);
}
_queue.push(data);
pthread_mutex_unlock(&_mutex);
pthread_cond_signal(&_cond_con);
return true;
}
bool Pop(ThreadTask *data) {
pthread_mutex_lock(&_mutex);
while(_queue.empty() == true) {
pthread_cond_wait(&_cond_con, &_mutex);
}
*data = _queue.front();
_queue.pop();
pthread_mutex_unlock(&_mutex);
pthread_cond_signal(&_cond_pro);
return true;
}
};
class Threadpool{
private:
int _max_thread;// Maximum number of threads
int _max_queue;// The maximum number of nodes in the task queue
BlockQueue _queue;
public:
Threadpool(int max_thr=MAX_THREAD, int max_q=MAXQ):
_max_thread(max_thr),
_max_queue(max_q), _queue(max_q){
pthread_t tid;
int ret;
for (int i = 0; i < max_thr; i++) {
ret = pthread_create(&tid, NULL, thr_entry, this);
if (ret != 0) {
printf("thread create error\n");
exit(-1);
}
pthread_detach(tid);
}
}
static void *thr_entry(void *arg){
Threadpool *pool = (Threadpool*)arg;
while(1) {
ThreadTask task;
pool->_queue.Pop(&task);
task.Run();
}
}
bool TaskPush(const ThreadTask &task) {
_queue.Push(task);
}
};
The singleton pattern
Aimed at the scene : A class can only instantiate one object , Provide an access interface , In other words, a resource can only have one copy in memory
Purpose : To save memory ; Prevent data ambiguity ;
Concrete realization
Hungry and lazy mode
All hungry resources are loaded in advance and initialized , Use it directly when you use it ( Space for time )
- Constructor privatization , Cannot instantiate object outside class
- Instantiate globally unique objects within classes , Resources are shared separately , Pre run initialization , The initialization process does not consider thread safety issues
lazy : Load when resources are used ( It's used a lot )
- Constructor private
- Lock the access interface to protect the resource initialization loading process
- Second test , Prevent lock conflicts , Increase of efficiency
- Prevent the compiler from over Optimizing , Use volatile Modify pointer member variables
// Starving model
class Singleton
{
public:
static Singleton* GetInstance()
{
return &_instance;
}
private:
Singleton(){};
Singleton(Singleton const&);
static Singleton _instance;// Global unique object
};
// The sluggard model
class Singleton
{
public:
volatile static Singleton* GetInstance()
{
if (_instance == nullptr)
{
m_mutex.lock();
if (_instance == nullptr)
{
_instance = new Singleton();
}
m_mutex.unlock();
}
return _instance;
}
private:
Singleton() {};// Constructor private
volatile static Singleton* _instance;// Singleton object pointer
static mutex m_mutex;// The mutex
};
边栏推荐
- 高级软考(网络规划设计师)该如何备考?
- 软考中级,软件设计师考试那些内容,考试大纲什么的?
- 2022.7.4DAY596
- Deconstruction and assignment of variables
- Unity websocket server
- Kitex retry mechanism
- P1223 queuing for water /1319: [example 6.1] queuing for water
- Simple and easy to modify spring frame components
- uniCloud
- A case of compiling QT file qmake compiling script
猜你喜欢
在线硬核工具
软考中级,软件设计师考试那些内容,考试大纲什么的?
【推荐系统 01】Rechub
[pro test feasible] error while loading shared libraries solution
What does intermediate software evaluator test
shardingsphere分库分表示例(逻辑表,真实表,绑定表,广播表,单表)
[untitled]
Unable to open kernel device '\.\vmcidev\vmx': operation completed successfully. Reboot after installing vmware workstation? Module "devicepoweron" failed to start. Failed to start the virtual machine
Différences entre les contraintes monotones et anti - monotones
Deep understanding of Apache Hudi asynchronous indexing mechanism
随机推荐
滚动踩坑--UNI_APP(八)
Go Slice 比较
[recommendation system 02] deepfm, youtubednn, DSSM, MMOE
Idea shortcut keys
软考信息处理技术员有哪些备考资料与方法?
Rolling puddle Uni_ App (VIII)
SQL Server 知识汇集9 : 修改数据
What does intermediate software evaluator test
SQL Server 知识汇集11 : 约束
2022年上半年5月网络工程师试题及答案
[recommendation system 01] rechub
[pyqt] the cellwidget in tablewidget uses signal and slot mechanism
[STM32] actual combat 3.1 - drive 42 stepper motors with STM32 and tb6600 drivers (I)
Wallhaven wallpaper desktop version
Seata 1.3.0 four modes to solve distributed transactions (at, TCC, Saga, XA)
單調性約束與反單調性約束的區別 monotonicity and anti-monotonicity constraint
Online hard core tools
【pyqt】tableWidget里的cellWidget使用信号与槽机制
Introduction to shell programming
A case of compiling QT file qmake compiling script