Loading [Contrib]/a11y/accessibility-menu.js

简易线程池的实现

 


1 线程池

为了避免多线程操作过程种线程频繁申请和释放所带来的性能消耗,可以提前创建多个线程,当有任务到来时从线程池中选择一个线程执行,执行完后继续在线程池中待命。

核心是使用一个工作队列,主线程往工作队列中添加工作,工作线程从队列中取出工作并执行。

对工作队列的操作就是经典的生产者—消费者模型,需要用到互斥锁和条件变量。

 

2 工作定义

通过函数指针指向执行函数。

1
2
3
4
typedef struct Task{
    void (*func)(void* arg);
    void* arg;
}Task;

  

3 线程池定义

使用 list 容器来存储工作,定义工作队列的最大数 m_max_requests 和 线程总数 m_max_threads。在对工作队列操作时需要用到互斥锁 m_mutex_pool,条件变量 m_notfull 和 m_notempty。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
class ThreadPool{
public:
    ThreadPool(int m_max_threads, int m_max_requests);
    ~ThreadPool();
    bool addWork(void(*func)(void*), void* arg);
 
private:
    static void* worker(void* arg);
    void run();
 
private:
    std::list<Task*> m_workqueue;  /*工作队列*/
    int m_max_requests;  /*请求队列中允许的最大请求数*/
    int m_max_threads;  /*线程总数*/
 
    pthread_t* m_worker_threads;  /*工作线程*/
 
    pthread_mutex_t m_mutex_pool;
 
    pthread_cond_t m_notfull;
    pthread_cond_t m_notempty;
 
    bool m_stop;
};
 
 
ThreadPool::ThreadPool(int m_max_threads, int m_max_requests):
        m_max_threads(m_max_threads), m_max_requests(m_max_requests), m_stop(false){
     
    if(m_max_threads <= 0 || m_max_requests <= 0){
        throw std::exception();
    }
     
    /*创建线程池*/
    m_worker_threads = new pthread_t[m_max_threads];
    if(!m_worker_threads){
        throw std::exception();
    }
    //memset(m_worker_threads, 0, sizeof(m_worker_threads));
 
    /*初始化互斥锁、条件变量*/
    if(0 != pthread_mutex_init(&m_mutex_pool, NULL) ||
       0 != pthread_cond_init(&m_notfull, NULL) ||
       0 != pthread_cond_init(&m_notempty, NULL)){
           throw std::exception();
       }
     
 
    /*创建工作线程*/
    for(int i=0; i<m_max_threads; ++i){
        printf("Create the %dth thread\n", i);
        if(0 != pthread_create(&m_worker_threads[i], 0, worker, this)){
            delete []m_worker_threads;
            throw std::exception();
        };
 
        if(pthread_detach(m_worker_threads[i])){
            delete [] m_worker_threads;
            throw std::exception();
        }
    }
}
 
 
ThreadPool::~ThreadPool(){
    delete []m_worker_threads;
    m_stop = true;
}
 
 
bool ThreadPool::addWork(void(*func)(void*), void* arg){
    pthread_mutex_lock(&m_mutex_pool);
    while(!m_stop && m_workqueue.size() >= m_max_requests){
        pthread_cond_wait(&m_notfull, &m_mutex_pool);
    }
    if(m_stop){
        pthread_mutex_unlock(&m_mutex_pool);
        return false;
    }
 
    /*添加工作*/
    Task* task = new Task;
    task->func = func;
    task->arg = arg;
    m_workqueue.push_back(task);
 
    pthread_mutex_unlock(&m_mutex_pool);
    pthread_cond_signal(&m_notempty);
     
    return true;
}
 
 
void* ThreadPool::worker(void* arg){
    ThreadPool* pool = (ThreadPool*)arg;
    pool->run();
    return pool;
}
 
void ThreadPool::run(){
    while(1){
        pthread_mutex_lock(&m_mutex_pool);
        while(m_workqueue.empty() && !m_stop){
            pthread_cond_wait(&m_notempty, &m_mutex_pool);
        }
 
        /*从工作队列中取任务*/
        Task* task = m_workqueue.front();
        m_workqueue.pop_front();
 
        pthread_mutex_unlock(&m_mutex_pool);
        pthread_cond_signal(&m_notfull);
 
        printf("Thread %ld start working...\n", pthread_self());
 
        /*执行任务*/
        task->func(task->arg);
        delete task;
 
        printf("Thread %ld end working...\n", pthread_self());
 
    }
}
 
 
#endif

  

4 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "threadpool.h"
#include<iostream>
#include<unistd.h>
using namespace std;
 
void taskFunc(void* arg)
{
    int num = *(int*)arg;
    printf("Thread %ld is working, number = %d\n", pthread_self(), num);
    sleep(1);
}
 
 
int main(){
    ThreadPool* pool = new ThreadPool(10, 20);
    for (int i = 0; i < 100; ++i)
    {
        int* num = (int*)malloc(sizeof(int));
        *num = i;
        pool->addWork(taskFunc, num);
    }
 
    sleep(30);
 
    return 0;
}

 

 

References:

  1. 手写线程池 - C 语言版
  2. 《Linux高性能服务器编程》


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   Kayden_Cheung  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2019-04-20 Redhat更换yum源
//目录
点击右上角即可分享
微信分享提示