线程池代码

2023-11-20

线程池

Global.h

#pragma once

const int DEFAULT_POOL_SIZE = 10;
const int STARTED = 0;
const int STOPPED = 1;

Mutex.h

#pragma once

#include <pthread.h>
#include <unistd.h>
#include <deque>
#include <iostream>
#include <vector>
#include <errno.h>
#include <string.h>

#include "Global.h"

using namespace std;

class Mutex
{
public:
    Mutex();
    ~Mutex();
	void lock();
    void unlock();
    pthread_mutex_t* get_mutex_ptr();
  
private:
    pthread_mutex_t m_lock;
    volatile bool is_locked;
};

Mutex.cpp

#include "Mutex.h"

Mutex::Mutex()
{
    pthread_mutex_init(&m_lock, NULL);
    is_locked = false;
}

Mutex::~Mutex()
{
    while(is_locked);
    unlock();
    pthread_mutex_destroy(&m_lock);
}

void Mutex::lock()
{
    pthread_mutex_lock(&m_lock);
    is_locked = true;
}

void Mutex::unlock()
{
    is_locked = false;
    pthread_mutex_unlock(&m_lock);
}

pthread_mutex_t* get_mutex_ptr()
{
	return &m_lock;
}

CondVar.h

#pragma once

#include <pthread.h>
#include <unistd.h>
#include <deque>
#include <iostream>

#include "Global.h"
using namespace std;

class CondVar
{
public:
    CondVar();
    ~CondVar();
    void wait(pthread_mutex_t* mutex);
    void signal();
    void broadcast();
private:
    pthread_cond_t m_cond_var;
};

CondVar.cpp

#include "CondVar.h"

CondVar::CondVar()
{
	pthread_cond_init(&m_cond_var, NULL);
}

CondVar::~CondVar()
{
    pthread_cond_destroy(&m_cond_var);
}

void CondVar::signal()
{
    pthread_cond_signal(&m_cond_var);
}

void CondVar::wait(pthread_mutex_t* mutex)
{
    pthread_cond_wait(&m_cond_var, mutex);
}

void CondVar::broadcast()
{
    pthread_cond_broadcast(&m_cond_var);
}

Task.h

#pragma once

#include <pthread.h>
#include <unistd.h>
#include <deque>
#include <iostream>
#include <errno.h>
#include <string.h>

#include "Global.h"

using namespace std;

class Task
{
public:
    Task(void (*fn_ptr)(void*), void* arg);
    ~Task();
    void operator()();
    void run();
    
private:
    void (*m_fn_ptr)(void*);
    void* m_arg;
};

Task.cpp

#pragma once

#include "Task.h"

Task::Task(void (*fn_ptr)(void*), void* arg) : m_fn_ptr(fn_ptr), m_arg(arg)();

Task::~Task(){}

void Task::operator()()
{
    (*m_fn_ptr)(m_arg);
}

void Task::run()
{
    (*m_fn_ptr)(m_arg);
}

ThreadPool.h

#pragma once

#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <errno.h>
#include <vector>

#include "Mutex.h"
#include "Task.h"
#include "CondVar.h"
#include "Global.h"

class ThreadPool
{
public:
    ThreadPool();
    ThreadPool(int pool_size);
    ~ThreadPool();
    int initialize_threadpool();
    int destroy_threadpool();
    void* execute_thread();
    int add_task(Task* task);
    
private:
    int m_pool_size;
    Mutex m_task_mutex;
    CondVar m_task_cond_var;
    vector<pthread_t> m_threads;
    deque<Task*> m_tasks;
    volatile int m_pool_state;
};

ThreadPool.cpp

#pragma once

#include "ThreadPool.h"

ThreadPool::ThreadPool() : m_pool_size(DEFAULT_POOL_SIZE)
{
	cout << "Constructed ThreadPool of size " << m_pool_size << endl;
}

ThreadPool::ThreadPool(int pool_size) : m_pool_size(pool_size)
{
    cout << "Constructed ThreadPool of size " << m_pool_size << endl;
}

ThreadPool::~ThreadPool()
{
	if(m_pool_state != STOPPED)
        destroy_threadpool();
}

extern "C"
void* start_thread(void* arg)
{
    ThreadPool* tp = (ThreadPool*)arg;
    tp->execute_thread();
    return NULL;
}
int ThreadPool::initialize_threadpool()
{
  m_pool_state = STARTED;
  int ret = -1;
  for (int i = 0; i < m_pool_size; i++) {
    pthread_t tid;
    ret = pthread_create(&tid, NULL, start_thread, (void*) this);
    if (ret != 0) {
      cerr << "pthread_create() failed: " << ret << endl;
      return -1;
    }
    m_threads.push_back(tid);
  }
  cout << m_pool_size << " threads created by the thread pool" << endl;

  return 0;
}

int ThreadPool::destroy_threadpool()
{
  m_task_mutex.lock();
  m_pool_state = STOPPED;
  m_task_mutex.unlock();
  cout << "Broadcasting STOP signal to all threads..." << endl;
  m_task_cond_var.broadcast(); // notify all threads we are shttung down

  int ret = -1;
  for (int i = 0; i < m_pool_size; i++) {
    void* result;
    ret = pthread_join(m_threads[i], &result);
    cout << "pthread_join() returned " << ret << ": " << strerror(errno) << endl;
    m_task_cond_var.broadcast(); 
  }
  cout << m_pool_size << " threads exited from the thread pool" << endl;
  return 0;
}

void* ThreadPool::execute_thread()
{
  Task* task = NULL;
  cout << "Starting thread " << pthread_self() << endl;
  while(true) {
    cout << "Locking: " << pthread_self() << endl;
    m_task_mutex.lock();
    
    while ((m_pool_state != STOPPED) && (m_tasks.empty())) {
      cout << "Unlocking and waiting: " << pthread_self() << endl;
      m_task_cond_var.wait(m_task_mutex.get_mutex_ptr());
      cout << "Signaled and locking: " << pthread_self() << endl;
    }

    if (m_pool_state == STOPPED) {
      cout << "Unlocking and exiting: " << pthread_self() << endl;
      m_task_mutex.unlock();
      pthread_exit(NULL);
    }

    task = m_tasks.front();
    m_tasks.pop_front();
    cout << "Unlocking: " << pthread_self() << endl;
    m_task_mutex.unlock();

    (*task)(); 
    delete task;
  }
  return NULL;
}

int ThreadPool::add_task(Task* task)
{
  m_task_mutex.lock();
  m_tasks.push_back(task);
  m_task_cond_var.signal(); 
  m_task_mutex.unlock();
  return 0;
}

Makefile

OBJPATH=bin/obj
EXAMPLEPATH=bin/example

all:
	g++ CondVar.cpp -lpthread -c -o $(OBJPATH)/CondVar.o
	g++ Mutex.cpp -lpthread -c -o $(OBJPATH)/Mutex.o
	g++ Task.cpp -lpthread -c -o $(OBJPATH)/Task.o
	g++ ThreadPool.cpp -lpthread -c -o $(OBJPATH)/ThreadPool.o
	g++ $(OBJPATH)/CondVar.o $(OBJPATH)/Mutex.o $(OBJPATH)/Task.o $(OBJPATH)/ThreadPool.o threadpool_test.cpp -lpthread -o $(EXAMPLEPATH)threadpool_test

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程池代码 的相关文章

随机推荐

  • centos8安装rabbitmq(rpm包)

    1 先下载好rpm包 https pkgs org 1 检索rabbitmq下载对应centos8的版本 rabbitmq server 3 9 14 1 el8 noarch rpm 2 检索erlang下载对应centos8的版本 在官
  • delphi 后台截图

    function PrintWindow SourceWindow hwnd Destination hdc nFlags cardinal bool stdcall external user32 dll name PrintWindow
  • Windows slmgr.vbs 命令详解

    系统软件授权管理工具主要是用来查看系统的激活状态 以及密钥许可证等信息 在现在不在是使用 接参数了 现在 接参数 详解可以在cmd窗口输入slmgr vbs了解 常用参数 使用方式 再次提醒是使用 而不是 ipk 配合密钥使用 安装密钥 替
  • 基于google升级版c++代码规范指南

    有些团队所有成员写的代码都一致 10个人写的代码像1个人写的 正因为有代码规范 使得代码可读性强 方便代码review 利于后期维护 这体现了代码规范的重要性 接下来 在参考google的代码规范基础上 详细列举代码规范细节 1 文件描述
  • matlab 怎么使用function,Matlab怎么调用函数 自定义函数使用方法

    Matlab作为一款专业性极强的商业数学软件 将诸多的算法开发 统计分析 数据可视化功能融入其中 用户可以方便地调用需要的函数 建立数学模型 为了满足你工作的需要 还可以自行设置自己需要的函数 下面就跟小编了解下吧 类别 理科工具 大小 1
  • Unix Network Programming Episode 77

    gethostbyaddr Function The function gethostbyaddr takes a binary IPv4 address and tries to find the hostname correspondi
  • time_wait的快速回收和重用

    问题现象 PC与工控机之间通信 工控机发送SYN PC一直回复FIN或者RST 问题解释 1 time wait产生的原因及作用 下面我们先来简单回顾一下TCP连接关闭动作 在Linux环境下我们可以如下的方式来统计TCP连接的情况 net
  • 高防服务器如何防止网站攻击,高防服务器怎么防御攻击的?

    高防服务器怎么防御攻击的 高防服务器 从字面上来理解就是具备防御性能的服务器 高防服务器相较于普通的服务器除了超高的防御性能以外 在配置上通常也是比较高的 所以在使用上 会更稳定一些 所以深受各类行业站长的喜爱 如今 很多企业在选择租用服务
  • C语言之冒泡排序法

    首先 还是老规矩先上代码 include
  • 数组双指针法汇总

    指针移动方向 相向夹逼 同向移动 维护的是一个区间还是只是关心指针指向的两个元素 同向移动的 维护一个区间的双指针法即滑动窗口法 2Sum 排序后两头往中间夹逼的双指针法 指针为什么可以不回退 即为什么可以i只 j只 当A i A j
  • jvm学习——7.运行时数据区之堆

    一个进程对应一个jvm实例 一个运行时数据区 又包含多个线程 这些线程共享了方法区和堆 每个线程包含了程序计数器 本地方法栈和虚拟机栈 66 核心概述 1 一个jvm实例只存在一个堆内存 堆也是java内存管理的核心区域 2 Java堆区在
  • kuboard获取token命令

    输入命令查看 echo kubectl n kube system get secret kubectl n kube system get secret grep kuboard user awk print 1 o go templat
  • u8系统怎么连接服务器,u8客户端连接服务器流程

    u8客户端连接服务器流程 内容精选 换一换 请点击下载 下载并安装桌面版客户端 您已经从企业的会议管理员那儿获取用户帐号了吗 快使用用户帐号登录客户端 开启会议之旅 桌面客户端定位基于电脑使用 在会议室中不支持接入鹅颈麦克风 音箱等外设使用
  • QT的QListWidget之单击双击增删改详解

    QListWidget是列表框控件 它是通过QListWidgetItem列表项来进行操作 我们的增删改操作也是围绕着它来开展 需要注意的是 删除操作 需要先断开QListWidget的信号和槽连接 否则会程序崩溃 void MainWin
  • opencv畸变校正的两种方法

    opencv中畸变校正有两种方法 1 undistort 直接进行畸变校正 void cv undistort InputArray src 原始图像 OutputArray dst 矫正图像 InputArray cameraMatrix
  • echarts中的地图展示所有省份以及悬浮上去展示具体的信息

  • stm32 HAL库 Flash操作简介

    stm32 HAL库 Flash操作简介 目录 第一stm32 flash介绍 查看代码段 以判断代码长度 flash的基本操作规则 stm32 HAL库 Flash操作指南 stm32f1xx hal flash c stm32f1xx
  • 在家做什么手工赚钱,这5种比较适合在家操作!

    对于很多怀孕的女生来说 呆在家里确实很无聊 大部分人呆在家里只能看看电视 玩玩手机 很多的孕妈都会抱怨 真是无聊透了 所以对于很多的孕妈来说 都想找点事做来缓解自己无聊的情绪 避免得了抑郁症 给宝宝带来不好的环境 那么怀孕在家里 有什么轻松
  • SpringSecurity的使用和流程详解(二)

    文章目录 登录 准备工作 核心代码 校验 准备工作 核心代码 测试 退出登录 登录 准备工作 添加依赖
  • 线程池代码

    线程池 Global h pragma once const int DEFAULT POOL SIZE 10 const int STARTED 0 const int STOPPED 1 Mutex h pragma once incl