my_thread_pool.h
//
// Created by ACE on 2021/10/20.
//
#ifndef CPPTEST_MY_THREAD_POOL_H
#define CPPTEST_MY_THREAD_POOL_H
#include <pthread.h>
struct my_task {
struct my_task *pNext;
int value;
};
struct my_thread_info {
//线程退出标志
int thread_running;
int thread_num;
int tasknum;
struct my_task *tasks;
pthread_t *threadid;
pthread_mutex_t mutex;
pthread_cond_t cond;
};
class my_thread_pool {
public:
my_task mt;//会自动分配空间;未使用
my_thread_info mti;//未使用
/* 初始化线程池线程数目
* @param thread_num 线程数目, 默认为8个
*/
my_thread_pool(int thread_num);
/* 销毁线程池
*/
~my_thread_pool();
/**向任务池中添加一个任务
* @param t 需要添加的任务
*/
//静态函数
static void my_thread_pool_add_task(struct my_task *t);
/**从任务池中取出一个任务
* @return 返回得到的任务
*/
static my_task *my_thread_pool_pop_task();
/**执行任务池中的任务
* @param t 需要执行的任务
*/
static void my_thread_pool_do_task(struct my_task *t);
/**线程函数
* @param thread_param 线程参数
*/
static void *my_thread_routine(void *thread_param) ;
};
#endif //CPPTEST_MY_THREAD_POOL_H
main.cpp
#include "my_thread_pool.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct my_thread_info g_threadinfo;
//成员函数定义
my_thread_pool::my_thread_pool(int thread_num)
{
if (thread_num <= 0)
thread_num = 5;
pthread_mutex_init(&g_threadinfo.mutex, NULL);
pthread_cond_init(&g_threadinfo.cond, NULL);
g_threadinfo.thread_num = thread_num;
g_threadinfo.thread_running = 1;
g_threadinfo.tasknum = 0;
g_threadinfo.tasks = NULL;
g_threadinfo.threadid = (pthread_t*)malloc(sizeof(pthread_t) * thread_num);
int i;
for (i = 0; i < thread_num; ++i)
{
pthread_create(&g_threadinfo.threadid[i], NULL, my_thread_routine, NULL);
}
}
//成员函数定义
my_thread_pool::~my_thread_pool()
{
g_threadinfo.thread_running = 0;
pthread_cond_broadcast(&g_threadinfo.cond);
for (int i = 0; i < g_threadinfo.thread_num; ++i)
{
pthread_join(g_threadinfo.threadid[i], NULL);
}
free(g_threadinfo.threadid);
pthread_mutex_destroy(&g_threadinfo.mutex);
pthread_cond_destroy(&g_threadinfo.cond);
}
//成员函数定义
void my_thread_pool::my_thread_pool_add_task(struct my_task* t)
{
if (t == NULL)
return;
pthread_mutex_lock(&g_threadinfo.mutex);
struct my_task* head = g_threadinfo.tasks;
if (head == NULL)
g_threadinfo.tasks = t;
else
{
while (head->pNext != NULL)
{
head = head->pNext;
}
head->pNext = t;
}
++g_threadinfo.tasknum;
//pthread_cond_signal将使用信号(signal)通知pthread_cond_wait函数
pthread_cond_signal(&g_threadinfo.cond);
pthread_mutex_unlock(&g_threadinfo.mutex);
}
//成员函数定义
my_task* my_thread_pool::my_thread_pool_pop_task()
{
struct my_task* head = g_threadinfo.tasks;
if (head != NULL)
{
g_threadinfo.tasks = head->pNext;
--g_threadinfo.tasknum;
printf("pop a task, task value is [%d]\n", head->value);
return head;
}
printf("no task\n");
return NULL;
}
//成员函数定义
void* my_thread_pool::my_thread_routine(void* thread_param)
{
printf("thread NO.%d start.\n", (int)pthread_self());
while (g_threadinfo.thread_running)
{
struct my_task* current = NULL;
pthread_mutex_lock(&g_threadinfo.mutex);
while (g_threadinfo.tasknum <= 0)
{
//如果获得了互斥锁,但是条件不合适的话,wait会释放锁,不往下执行
//当变化后,条件合适,将直接获得锁
pthread_cond_wait(&g_threadinfo.cond, &g_threadinfo.mutex);
if (!g_threadinfo.thread_running)
break;
}// end inner-while-loop
current = my_thread_pool_pop_task();
pthread_mutex_unlock(&g_threadinfo.mutex);
my_thread_pool_do_task(current);
}// end outer-while-loop
printf("thread :%d exited.\n", (int)pthread_self());
return nullptr;
}
//成员函数定义
void my_thread_pool::my_thread_pool_do_task(struct my_task* t)
{
if (t == NULL)
return;
//业务处理的地方
printf("do task [%d]\n", t->value);
//如果t需要释放,在这里释放
}
int main(int argc, char* argv[])
{
my_thread_pool* myt = new my_thread_pool(5);
my_task* task = NULL;
for (int i = 0; i < 100; ++i)
{
task = (my_task*)malloc(sizeof(my_task));
task->value = i + 1;
task->pNext = NULL;
printf("add task, task value [%d]\n", task->value);
myt->my_thread_pool_add_task(task);
}
sleep(10);
delete(myt);
return 0;
}
注:
int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);
返回值:函数成功返回0;任何其他返回值都表示错误
函数将解锁mutex参数指向的互斥锁,并使当前线程阻塞在cv参数指向的条件变量上。
被阻塞的线程可以被pthread_cond_signal函数,pthread_cond_broadcast函数唤醒,也可能在被信号中断后被唤醒。
int pthread_cond_signal(pthread_cond_t *cv);
返回值:函数成功返回0;任何其他返回值都表示错误
函数被用来释放被阻塞在指定条件变量上的一个线程。
必须在互斥锁的保护下使用相应的条件变量。否则对条件变量的解锁有可能发生在锁定条件变量之前,从而造成死锁。