手撕线程池

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*/

全部评论
这都要手写?
点赞 回复 分享
发布于 2022-04-19 23:34
std::bind和forward了解一下
点赞 回复 分享
发布于 2018-09-18 01:00
会有面试要手写吗。。害怕😨
点赞 回复 分享
发布于 2018-09-17 23:59

相关推荐

评论
1
17
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务