目录
🌥️3.3.1 __threads_create & __threads_terminate
🌥️3.3.3 __add_task & __pop_task
🌤️1. 基础知识
⛅1.1 线程概述
要实现线程池,首先要了解什么是线程?要说线程就不得不提进程,以 Windows 下 QQ 为例,当我们双击打开 QQ,便打开了一个 QQ 进程,进程可以简单的认为是程序的一次执行过程,是操作系统分配基本运行资源的基本单位,可以通过任务管理器查看每一个进程的资源(如 CPU、内存、磁盘、网络)使用情况。在 QQ 中,我们可以同时打字聊天、语音通话、下载文件等,在同一个进程 QQ 中,这些同时进行的任务就是由不同的线程来执行的。线程是进程内的一个执行单元,它与其他线程共享该进程的资源,每个线程都拥有自己的执行序列、程序计数器、寄存器集和堆栈,线程是操作系统调度执行的最小单位。在 Linux 中,其实进程和线程不做区分,关于这些本质细节后面会出专门的专栏进行讲解,现在只需要知道线程就是来执行某个特定任务的。
⛅1.2 linux下线程相关函数
为了实现线程池,还需要掌握一些常见的线程函数。
🌥️1.2.1 线程ID
每一个线程都有一个唯一的线程ID,类型为pthread_t,一个无符号长整形数,可以调用如下函数获得:
pthread_t pthread_self(void); // 返回当前线程的线程ID
🌥️1.2.2 线程创建
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
// thread:线程ID;attr: 线程属性, 一般写NULL;start_routine:函数指针;arg:函数实参
// 返回值:成功返回0
给大家举个例子就明白怎么创建一个线程了。
可以这样来理解线程创建函数:tid作为标记值管理线程,就像用fd来管理文件描述符一样,学号来管理学生一样,作为唯一不可重复的标识,线程是用来处理任务的,所以要传一个函数指针,这个任务函数可能有参数,所以还要传入参数。
🌥️1.2.3 线程回收
#include <pthread.h>
// 这是一个阻塞函数, 子线程在运行这个函数就阻塞,直到子线程退出, 函数解除阻塞, 回收对应的子线程资源
int pthread_join(pthread_t thread, void **retval);
// thread:线程ID;retval:一般写NULL
// 返回值:成功返回0
有线程创建就必有线程回收,这个函数调用之后,主线程(一般为main函数)要阻塞等待所有的子线程完成,所以效率较低。
🌥️1.2.4 线程分离
在很多情况下,主线程有属于自己的业务处理流程,调用pthread_join()只要子线程不退出主线程就会一直被阻塞。为了解决这种效率低的问题,线程库函数为我们提供了线程分离函数pthread_detach()