最近学习了一些线程池方面的内容,根据学习的内容,使用C++,基于pthread线程库实现了一个简单线程池,水平有限,可能存在很多不足,代码如下
threadpool.cpp
#include "threadpool.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
CThreadPool::CThreadPool(const std::string &name)
: m_Name(name), m_Threads(NULL), m_ThreadNum(0), m_QueueSize(0), m_Running(false)
{
}
CThreadPool::~CThreadPool()
{
if (m_Running)
{
Stop();
}
}
int CThreadPool::Init(int thread_num, int queue_num)
{
if (thread_num <= 0 || queue_num <= 0)
return -1;
m_QueueSize = queue_num;
if (pthread_mutex_init(&m_Mutex, NULL) != 0)
{
printf("pthread_mutex_init fail\n");
return -1;
}
if (pthread_cond_init(&m_QueueNotFull, NULL) != 0)
{
printf("pthread_cond_init fail\n");
goto err1;
}
if (pthread_cond_init(&m_QueueNotEmpty, NULL) != 0)
{
printf("pthread_cond_init fail\n");
goto err2;
}
m_ThreadNum = thread_num;
m_Threads = (pthread_t *)calloc(thread_num, sizeof(pthread_t));
if (m_Threads == NULL)
{
printf("malloc fail\n");
goto err3;
}
m_Running = true;
for (int i = 0; i < thread_num; i++)
{
if (pthread_create(&m_Threads[i], NULL, thread_task, this) != 0)
{
printf("pthread_create fail\n");
goto err4;
}
}
return 1;
err4:
free(m_Threads);
err3:
pthread_cond_destroy(&m_QueueNotEmpty);
err2:
pthread_cond_destroy(&m_QueueNotFull);
err1:
pthread_mutex_destroy(&m_Mutex);
return -1;
}
void CThreadPool::Stop()
{
if (!m_Running)
return;
m_Running = false;
pthread_cond_broadcast(&m_QueueNotEmpty);
pthread_cond_broadcast(&m_QueueNotFull);
for (size_t i = 0; i < m_ThreadNum; i++)
{
pthread_join(m_Threads[i], NULL);
}
free(m_Threads);
m_Threads = NULL;
pthread_mutex_lock(&m_Mutex);
pthread_mutex_destroy(&m_Mutex);
pthread_cond_destroy(&m_QueueNotEmpty);
pthread_cond_destroy(&m_QueueNotFull);
}
int CThreadPool::AddTask(func_type func, void *arg)
{
pthread_mutex_lock(&m_Mutex);
while (m_Tasks.size() == m_QueueSize && m_Running)
{
pthread_cond_wait(&m_QueueNotFull, &m_Mutex);
}
if (!m_Running)
{
pthread_mutex_unlock(&m_Mutex);
printf("线程池已经停止工作了。。。\n");
return -1;
}
TaskInfo task;
task.func = func;
task.arg = arg;
m_Tasks.push(task);
pthread_mutex_unlock(&m_Mutex);
pthread_cond_signal(&m_QueueNotEmpty);
return 1;
}
int CThreadPool::GetTaskNum()
{
pthread_mutex_lock(&m_Mutex);
int ret = m_Tasks.size();
pthread_mutex_unlock(&m_Mutex);
return ret;
}
void *CThreadPool::thread_task(void *arg)
{
printf("thread_task thread id = %lu\n", pthread_self());
CThreadPool *thread_pool = (CThreadPool *)arg;
while (thread_pool->m_Running)
{
pthread_mutex_lock(&thread_pool->m_Mutex);
while (thread_pool->m_Tasks.empty() && thread_pool->m_Running)
{
pthread_cond_wait(&thread_pool->m_QueueNotEmpty, &thread_pool->m_Mutex);
}
if (!thread_pool->m_Running)
{
pthread_mutex_unlock(&thread_pool->m_Mutex);
break;
}
TaskInfo task = thread_pool->m_Tasks.front();
thread_pool->m_Tasks.pop();
pthread_mutex_unlock(&thread_pool->m_Mutex);
pthread_cond_signal(&thread_pool->m_QueueNotFull);
task.func(task.arg);
}
pthread_exit(NULL);
}
threadpool.h
#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__
#include <pthread.h>
#include <queue>
#include <string>
typedef void *(*func_type) (void *);
struct TaskInfo
{
func_type func;
void *arg;
};
class CThreadPool
{
public:
explicit CThreadPool(const std::string &name = "CThreadPool");
~CThreadPool();
int Init(int thread_num = 10, int queue_num = 64);
void Stop();
int AddTask(func_type func, void *arg);
int GetTaskNum();
const std::string &GetPoolName() const
{ return m_Name; }
private:
CThreadPool& operator=(const CThreadPool&);
CThreadPool(const CThreadPool&);
private:
static void *thread_task(void *arg);
private:
std::string m_Name;
pthread_mutex_t m_Mutex;
pthread_cond_t m_QueueNotFull;
pthread_cond_t m_QueueNotEmpty;
pthread_t *m_Threads;
size_t m_ThreadNum;
std::queue<TaskInfo> m_Tasks;
size_t m_QueueSize;
bool m_Running;
};
#endif
test.cpp
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include "threadpool.h"
#include <unistd.h>
#include <stdlib.h>
void *func(void *arg)
{
printf("[%lu] print:%s\n", pthread_self(), (char *)arg);
usleep(100);
return NULL;
}
//g++ threadpool.cpp test.cpp -o test -pthread -g -Wall
int main(int argc, char *argv[])
{
CThreadPool ctp;
int ret = ctp.Init(24, 128);
if (ret < 0)
{
printf("Init fail\n");
exit(EXIT_FAILURE);
}
printf("main thread id = [%lu]\n", pthread_self());
for (int i = 0; i < 10000; i++)
{
ctp.AddTask(func, (void *)"helloworld");
}
while (1)
{
printf("task num = %d\n", ctp.GetTaskNum());
if (ctp.GetTaskNum() == 0)
{
ctp.Stop();
break;
}
else
{
usleep(100);
}
}
return 0;
}
编译命令:
g++ threadpool.cpp test.cpp -o test -pthread -g -Wall