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系统里,进程是资源分配的基本单元,而线程则是程序执行和调试的最小单元。线程的开锁除了线程上下文 切换带来的开销外,这里还有另一个开销,那就是线程的创建与销毁,尤其是频繁使用线程的场景下,这种开销会特别明显。

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

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

相关推荐
寄存器漫游者16 分钟前
数据结构:带头节点单链表
c语言·数据结构
定偶26 分钟前
MySQL多表连接查询详解
c语言·数据库·mysql
呱呱巨基2 小时前
c语言 文件操作
c语言·开发语言·c++·笔记·学习
云小逸3 小时前
【Nmap 设备类型识别技术】整体概况
服务器·c语言·网络·c++·nmap
梵刹古音3 小时前
【C语言】 跳转语句
c语言·开发语言·算法
C语言小火车4 小时前
Qt样式实现方式详解:六大方法全面解析
c语言·c++·qt·学习
AllData公司负责人5 小时前
【亲测好用】实时开发平台能力演示
java·c语言·数据库
pcm1235675 小时前
设计C/S架构的IM通信软件(3)
java·c语言·架构
zz34572981135 小时前
C语言基础概念7
c语言·开发语言
二年级程序员6 小时前
C 语言文件操作
c语言