中山大学软件工程 操作系统原理 蔡国扬 线程池的实现 - Labweek_13

Labwork13 - ThreadPool Implementation

编译环境

一般:
System:
macOS Big Sur 11.2.3 - arm64
GNU: 
Apple clang version 12.0.0 (clang-1200.0.32.29)

备用:
System:
Ubuntu 20.04 LTS - arm64
GNU:
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

实验内容: 设计实现一个线程池 (Thread Pool)

  • 使用 Pthread API
  • FIFO
  • 先不考虑互斥问题
  • 编译、运行、测试用例

实验过程

一、实验准备

  1. 原理理论

首先,我们应该了解,什么是线程池,怎样去实现一个线程池。
通过查找资料我们可以得到如下程序框图:
线程池原理
在本次实验中,为简单起见,我们选择实现核心线程池。

  1. 实验实现

数据结构:

typedef struct task				// 数据结构 - 任务
{
    function_t func_ptr;		// 函数指针
    void * args;				// 函数参数
    struct task * next;			// 下一个任务
    struct task * prev;			// 上一个任务
} Task;

typedef struct					// 数据结构 - 线程池
{
    bool shutdown;				// 是否处在叫停状态
    int max_thread, num_tasks;	// 线程总数和线程数
    pthread_t *threads;			// 线程数组指针
    Task* head;					// 任务队列头指针
    Task* tail;					// 任务队列尾指针
    sem_t* queue_sem;			// 阻塞状态
} ThreadPool;

实现函数:

ThreadPool * tp_create(int);					// 创建线程池 
bool task_enqueue(ThreadPool*, Task*);			// 任务入队
Task* task_dequeue(ThreadPool*);				// 任务出队
void task_empty(ThreadPool*);					// 清除任务队列
bool add_task(ThreadPool*, function_t, void*);	// 添加任务
void tp_destory(ThreadPool*);					// 销毁线程池
void work_routine(void*);						// 线程工作

实现细节的原理性分析:

本实验中有关 Pthread API 相关内容在先前实验中已经多次使用,这里不再赘述。

  • 信号量semphone.h

    这一部分包括了sem_initsem_waitsem_postsem_destroy等函数,该部分的功能是实现了一个信号系统,它在各个线程均繁忙的情况下会阻塞任务队列中的内容进入线程,等待有线程空闲后再发送信号允许任务进入,通过semphone我们实现了控制任务队列的进出从而不会产生任务得不到执行的问题。

  • 互斥锁mutex

    本次实验不要求考虑互斥问题,但在实际实现过程中我们发现如果不使用互斥锁对操作进行锁定我们就会出现多个线程同时操纵线程池数据结构的问题,从而导致分支判断失效,实验失败。
    分支判断失效导致的非法队列操作
    我们使用 pthread_mutex 实现互斥锁后,此问题得到解决。

二、实验结果

根据实验所得,通过线程池中的20个线程,1000项任务的每一项均得到了解决,认为线程池已经实现。
在这里插入图片描述

三、实验心得

通过本次实验,我学习到了线程池的实现原理,能够实现一个简单的线程池供任务进入并执行,在实验过程中遇到了许多的问题,在遇到问题-解决问题的不断循环中拓宽了我对线程的总体了解,增强了自身解决问题的能力,同时对于POSIX编程有了更加全面的认识。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值