21xrx.com
2024-11-22 03:46:18 Friday
登录
文章检索 我的文章 写文章
C++手写线程池制作指南
2023-07-13 16:40:47 深夜i     --     --
C++ 手写 线程池 制作 指南

在进行多线程编程时,通常使用线程池来管理和分配线程任务,以达到提高程序性能和处理效率的目的。C++的线程池有很多现成的库可以使用,但是手写一个简单的线程池也是非常有益的练习。

下面是一个简单的手写C++线程池的制作指南。

1. 定义任务类

任务类通常包含需要执行的代码和相关的参数。在本例中,我们定义了一个名为“Task”的任务类,并在类中添加了一个名为“run”的方法,用于执行任务。

class Task {

public:

  Task() {}

  virtual ~Task() {}

  virtual void run() = 0;

};

2. 定义线程池类

线程池类通常用于管理任务和线程,包括任务队列,线程队列等。在这个例子中,我们定义了一个名为“ThreadPool”的线程池类,它包含了添加任务、开启线程、执行任务等方法。

class ThreadPool {

public:

  ThreadPool(int threadNum);

  virtual ~ThreadPool();

  void addTask(Task* task);

  void start();

  void stop();

private:

  int threadNum_;

  std::vector threads_;

  std::queue taskQueue_;

  std::mutex mtx_;

  std::condition_variable condition_;

  bool stop_;

};

3. 实现线程池类

在线程池类的实现中,我们首先需要定义类的构造函数和析构函数。在构造函数中,我们初始化了线程数量、停止标识,并启动了线程池。

ThreadPool::ThreadPool(int threadNum) : threadNum_(threadNum), stop_(false) {

  for(int i=0; i

    threads_.push_back(new std::thread(&ThreadPool::start, this));

  }

}

ThreadPool::~ThreadPool() {

  stop_ = true;

  condition_.notify_all();

  for(auto thread : threads_) {

    thread->join();

    delete thread;

  }

  threads_.clear();

}

在addTask方法中,我们将任务加入到任务队列中,并通知等待中的线程有新的任务可以执行。

void ThreadPool::addTask(Task* task) {

  std::unique_lock lock(mtx_);

  taskQueue_.push(task);

  condition_.notify_one();

}

在start方法中,我们没有直接执行任务,而是等待任务队列中有任务时才进行执行。线程会不断地从任务队列中取出任务,并执行任务的run方法。

void ThreadPool::start() {

  while(!stop_) {

    std::unique_lock lock(mtx_);

    while(taskQueue_.empty()) {

      if(stop_)

        return;

      condition_.wait(lock);

    }

    Task* task = taskQueue_.front();

    taskQueue_.pop();

    task->run();

    delete task;

  }

}

stop方法用于终止线程池,首先将停止标识置为true,然后通知所有等待中的线程,等待所有线程执行完任务后退出线程。

void ThreadPool::stop() {

  stop_ = true;

  condition_.notify_all();

}

4. 测试线程池类

在测试线程池类时,我们需要定义需要执行的任务。在本例中,我们定义了一个名为“PrintTask”的任务类,该任务类包含一个字符串参数,并在run方法中输出字符串。

class PrintTask : public Task {

public:

  PrintTask(const std::string& str) : str_(str) {}

  virtual ~PrintTask() {}

  virtual void run() std::cout << str_ << std::endl;

private:

  std::string str_;

};

在测试时,我们创建线程池并添加任务,然后等待所有任务执行完毕后,停止线程池。

int main() {

  ThreadPool threadPool(4);

  for(int i=0; i<10; i++) {

    threadPool.addTask(new PrintTask(std::to_string(i)));

  }

  threadPool.stop();

  return 0;

}

通过上述步骤,我们就完成了一个简单的手写C++线程池的制作。

需要注意的是,这个简单的线程池只包含最基本的功能,对于一些高级的线程池特性比如线程池扩展、任务优先级等暂不考虑。但是做到了这些,我们就可以更好地理解和使用现有的线程池库。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复