Linux中的线程是什么?

在现代Linux操作系统中,一个程序在运行时,进程是分配资源的基本单位,Linux内核先fork一个子进程,分配物理内存,然后将要执行的可执行文件加载到内存。每个进程都是相互独立的,进程之间如果需要通信则需要借助第三方工具。

不同的进程在切换运行时,CPU需要不停地保存现场、恢复现场,因此进程上下切换的开销是很大的。所以如果程序要并行执行很多任务,通过创建很多的进程来实现,不是个很好的主意。在现代linux操作系统中引入了线程,它的目的是为了减少进程的开销,就是减少进程的切换。一个进程可能存在多个线程,但它至少有一个线程。多个线程之间的关系就像在一个家里一样,每个人都有自己的房间,但饭厅、客厅、卫生间都是公用的。多个线程都有各自独立的资源,如程序计数器、寄存器上下文和各自的栈空间;但是进程中的代码段、数据段、地址空间、打开的文件、信号处理程序等资源都是共享的。这些共享的资源为了保证程序的正确性符合逻辑,这共享资源会涉及安全访问和线程间同步的问题,一般通过互斥锁、条件锁、读写锁等锁机制来实现对资源的安全访问。这是很好理解的,就像在家里的厕所有人正在使用,其他人就要等。

在C语言中,使用pthread库来实现多线程对共享资源的互斥访问:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 初始化互斥锁

int shared_num = 0; // 共享资源

void* thread_task(void* arg) {

pthread_mutex_lock(&mutex); // 加锁

shared_num++;

printf("共享变量值:%d\n", shared_num);

pthread_mutex_unlock(&mutex); // 解锁

pthread_exit(NULL); //退出程序

复制代码
加锁也会增加系统开销,即当程序调用加锁函数时,操作系统会从用户态切换到内核态,并阻塞在内核态;当程序调用解锁时,也经历从用户态切换到内核态,再从内核态切换回用户态。这告诉我们如果减少此类开锁,就要减少加锁、解锁的操作。

我们再来说说线程池,虽然进程的多个线程可以共享进程的很多资源,如代码段、数据段、打开的文件,线程们也有自己的上下文环境,如各自的寄存器状态、栈、程序计数器等。在现代linux系统里,进程是资源分配的基本单元,而线程则是程序执行和调试的最小单元。线程的开锁除了线程上下文 切换带来的开销外,这里还有另一个开销,那就是线程的创建与销毁,尤其是频繁使用线程的场景下,这种开销会特别明显。

为了减少线程不断创建与销毁带来的开销,可以实现一个线程池。预先创建一些线程,没有任务时,这些线程就阻塞在池中,有任务时,通过管理线程将任务分配到指定的线程来执行。

一般来说实现一个线程池需要有管理线程、工作线程和任务接口等组成。管理线程是用于创建和管理工作线程的,将用户创建的不同任务分配给不同的工作线程去执行;工作线程是真正做事的线程,它负责执行给过来的伤,没有任务时,就阻塞中池中。线程池一般会提供一些任务接口供用户创建不同的任务,这些任务会分配到不同的线程中去执行。

相关推荐
caishenzhibiao1 小时前
市场同步系统 同花顺期货通指标
java·c语言·c#
say_fall2 小时前
【Linux系统编程】文件操作基础:C标准库、系统调用、fd是什么和fd与FILE*的关系
android·linux·c语言
Lee_jerome14 小时前
《C/C++编译全家桶:g++四阶段、.a与.so区别、CMake构建、ARM交叉编译,这篇全讲透了》
c语言·开发语言·arm开发·c++·编译·cmake·cmakelists
浩浩kids15 小时前
C•exercises
c语言
春生野草16 小时前
个人笔记——C语言字符串、树
c语言·开发语言·笔记
ysu_031417 小时前
用Vibe-Coding从零实现俄罗斯方块
c语言·游戏程序
冻柠檬飞冰走茶21 小时前
PTA基础编程题目集 7-24 约分最简分式(C语言实现)
c语言·开发语言·数据结构·算法
weixin_585951171 天前
CH592F 2.4G 低功耗
c语言·开发语言
盒子里的加菲猫1 天前
什么?不会C语言也可以搭建窗口级应用程序?(Electron)
c语言·开发语言·electron
caishenzhibiao1 天前
无极多空共振 同花顺期货通指标
java·c语言·c#