手撕线程池
C++刚刚手撕了一遍,参考答案的基础上也要一个多小时,要是问起来,岂不是要跪了的。
#include "threadpool.h"
pthread_mutex_t ThreadPool::mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ThreadPool::cond = PTHREAD_COND_INITIALIZER;
std::vector<Task*> ThreadPool::tasks;
ThreadPool::ThreadPool(int threads) { this->threads = threads; this->shutdown = false; this->counter = 0; this->idle = 0;
}
void* ThreadPool::process(void *arg) { struct timespec abstime; int timeout; ThreadPool *pool = static_cast<ThreadPool*>(arg); printf("thread 0x%0x is starting\n", (int)pthread_self()); while (true) { pthread_mutex_lock(&mutex); pool->idle++; timeout = 0; while (tasks.empty() && !pool->shutdown) { clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += 2; int status = pthread_cond_timedwait(&cond, &mutex, &abstime); if (status == ETIMEDOUT) { printf("thread 0x%0x is waiting time out\n", (int)pthread_self()); timeout = -1; break; } } pool->idle--; if (!tasks.empty()) { Task *task = tasks.back(); tasks.pop_back(); // 执行任务 pthread_mutex_unlock(&mutex); task->run(task->arg); delete task; pthread_mutex_lock(&mutex); } if (pool->shutdown && tasks.empty()) { pool->counter--; if (pool->counter == 0) { pthread_cond_signal(&cond); } pthread_mutex_unlock(&mutex); break; } if (timeout == -1 && tasks.empty()) { pool->counter--; pthread_mutex_unlock(&mutex); break; } pthread_mutex_unlock(&mutex); } printf("thread 0x%0x is exiting\n", (int)pthread_self()); return NULL;
}
void ThreadPool::add_task(void* (*run)(void *arg), void *arg) { pthread_mutex_lock(&mutex); // 生成新的任务 Task *task = new Task; task->run = run; task->arg = arg; tasks.push_back(task); // 如果有等待线程,则唤醒一个 if (idle > 0) { pthread_cond_signal(&cond); } else if (counter < threads){ pthread_t tid; pthread_create(&tid, NULL, ThreadPool::process, (void*)this); this->counter++; } pthread_mutex_unlock(&mutex);
}
void ThreadPool::threadpool_destroy() { if (shutdown) { return; } pthread_mutex_lock(&mutex); shutdown = true; if (counter > 0) { // 唤醒空闲线程退出 if (idle > 0) { pthread_cond_broadcast(&cond); } // 如果线程处于执行阶段,等待任务执行完毕之后退出 while (counter > 0) { pthread_cond_wait(&cond, &mutex); } } pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex);
}
#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include <vector>
#include <pthread.h>
#include <time.h>
#include <errno.h>
#include <iostream>
struct Task { void* (*run)(void *arg); void *arg;
};
class ThreadPool {
private: int threads; static std::vector<Task*> tasks; static pthread_mutex_t mutex; static pthread_cond_t cond; static void *process(void *arg); bool shutdown; int counter; int idle;
public: ThreadPool(int threads_); ~ThreadPool() {}; void add_task(void* (*task)(void *arg), void *arg); void threadpool_destroy();
};
#endif /*_THREADPOOL_H*/
查看24道真题和解析