Linux —— 线程

Linux —— 线程

  • 什么是线程
  • Linux如何实现线程
  • Winodws如何实现线程
  • 使用一下线程
    • pthread_create
      • 函数原型
      • 参数说明
      • 返回值
    • 如何解决
  • ps -aL 查看线程
  • 线程为什么轻量

我们今天进入线程的学习:

什么是线程

我们先来了解一个笼统的概念:简单来说,线程(Thread)是操作系统能够进行运算调度的最小单位

这句话其实很抽象,我们来画个图来分析一下:

首先我们知道进程
在这里插入图片描述
然后,我们可以在此基础上,如果可以让多个PCB指向一个进程空间,可以提高执行效率:
在这里插入图片描述
然后,我们称红色的为线程
在这里插入图片描述
这里我们可以得到这样几个事实(概念):

  1. 进程是资源分配的基本单位,因为只有进程会有进程地址空间,才会运行。
  2. 线程是在进程类的,是进程的小弟,帮进程做事,自己和进程共享进程地址空间。

这个时候,我们再来看看线程的概念:

线程(Thread)是操作系统能够进行运算调度的最小单位它是进程内部的一个执行序列,代表了进程中一个单一的顺序控制流一个进程可以包含一个或多个线程,这些线程共享所属进程的内存空间和资源,比如代码段、数据段、文件句柄等,但每个线程都拥有自己的程序计数器、栈空间(调用栈)、寄存器组等执行上下文,以实现独立的执行路径。
线程的存在使得程序能够并发执行不同的任务,提高了程序的执行效率和响应速度,特别是在多核处理器系统中,多个线程可以同时在不同的CPU核心上运行,实现真正的并行处理。线程之间的协作和数据共享相对灵活,但同时也引入了资源竞争和同步问题,需要通过互斥锁、信号量等机制来解决潜在的竞态条件和死锁问题。
线程分为两类:内核线程(Kernel Thread)用户线程(User Thread)。内核线程直接由操作系统内核管理,其创建、调度和切换等操作都是在内核层面完成的;用户线程则由应用程序管理,有时需要借助于内核线程来实现多线程的并行执行。在某些系统中,还存在混合模式,如N:1模型(多个用户线程映射到一个内核线程)或M:N模型(多个用户线程映射到多个内核线程),以平衡用户态与内核态切换的成本和线程管理的灵活性。

Linux如何实现线程

Linux在实现线程上面偷了懒,并没有专门实现,而是对照进程:

Linux 实现线程的概念确实借鉴了进程的实现方式。在Linux内核中,没有专门的“线程”这一概念,而是将线程作为轻量级进程(Lightweight Processes, LWP)来处理。这意味着每个线程在内核中都表现为一个标准的进程,拥有自己的 task_struct,这是Linux内核中表示进程的核心结构体。然而,这些线程之间共享某些资源,如地址空间、文件描述符和信号处理等,这与传统意义上的独立进程不同。
Linux使用 clone() 系统调用来创建线程,该调用允许父子进程共享某些资源,同时保持独立的执行流和少量独立的状态,如线程ID、栈等。通过精心选择 clone() 的参数,可以创建具有不同资源共享级别的新执行实体,从而实现线程。通常,线程库如POSIX threads (pthreads) 会封装 clone() 系统调用,为程序员提供更高层次的线程创建和管理接口。

因此,可以说Linux中的线程实现是基于进程概念的扩展,利用了进程的基础设施并加以调整,以支持在同一进程内的多个执行流,同时保持高效的资源复用。

Winodws如何实现线程

Wnidows是专门实现了线程的概念:

是的,Windows操作系统实现了线程的概念。在Windows中,线程是执行代码的基本单位,而进程则是资源分配的最小单位,每个进程可以包含一个或多个线程。Windows通过一系列线程相关的API来支持线程的创建、管理和调度,这些API允许开发者创建、终止线程,设置线程的优先级,进行线程同步,以及管理线程的执行状态。
例如,使用CreateThread或更现代且功能更全面的CreateThreadEx函数可以创建一个新的线程;ExitThread用于结束一个线程;WaitForSingleObjectWaitForMultipleObjects可以用来同步线程;而SetThreadPriority可以改变线程的优先级等。此外,Windows还提供了线程局部存储、互斥量、信号量、事件等机制来帮助开发者管理线程间的通信和同步问题。

总之,Windows通过其内核对象和用户模式API全面支持了线程的概念,并且在设计上确保了线程能够在多处理器系统上有效地并行执行。

使用一下线程

我们可以使用一下线程的接口:
在这里插入图片描述

pthread_create

pthread_create函数是POSIX线程库(Pthreads)中的一个核心函数,用于在UNIX-like系统(如Linux、macOS等)中创建一个新的线程。这个函数允许程序实现多线程并发执行,提高执行效率和响应速度。以下是pthread_create函数的基本信息和用法:

函数原型

int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void *), void *restrict arg);

参数说明

  • tidp: 指向线程标识符(pthread_t类型)的指针,用于存储新创建线程的标识。成功创建后,线程的ID将被写入此地址。
  • attr: 一个指向pthread_attr_t结构的指针,该结构可以用来设置线程的属性,如栈大小、调度策略等。如果为NULL,则使用默认属性。
  • start_rtn: 指向线程开始执行的函数的指针,也就是线程的入口点。这个函数必须接收一个void *类型的参数,并返回一个void *类型的指针。
  • arg: 传递给线程入口函数的参数,类型为void *。在线程启动时,这个参数会被传递给start_rtn函数。

返回值

  • 如果成功创建线程,pthread_create返回0。
  • 如果出现错误(比如资源不足),则返回一个非零的错误码。
#include<iostream>
#include<unistd.h>
#include<pthread.h>// 线程函数,打印线程信息
void *ThreadRountine(void* arg)
{const char *thread_name = (const char*)arg; // 将参数转换为字符串while(true) // 无限循环{std::cout << "I am a thread process" << ",pid: "<< getpid()<< std::endl; // 打印线程信息sleep(1); // 休眠1秒}
}int main()
{pthread_t tid; // 定义线程ID// 创建线程,传入线程函数和参数pthread_create(&tid,nullptr,ThreadRountine,(void*)"thread 1");while(true) // 无限循环{std::cout << "I am the main thread"<< ",pid: "<< getpid()<< std::endl; // 打印主线程信息sleep(1); // 休眠1秒}return 0;
}

在这里插入图片描述

我们发现运行起来了,但是很乱,这是因为主线程和创建的子线程都在同时尝试向标准输出(stdout)写入内容,而std::cout的输出默认是非原子性的,即输出操作可以被其他线程中断。当多个线程并发写入时,它们可能交错打印,导致输出混乱

如何解决

上面的问题就是竞争,线程竞争我们在学习操作系统中,已经学习过许多方法,这里我们用来解决:

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <mutex> // 引入互斥锁std::mutex cout_mutex; // 全局互斥锁实例void *ThreadRoutine(void *arg) 
{const char *thread_name = (const char *)arg;while (true) {std::unique_lock<std::mutex> lock(cout_mutex); // 锁定互斥锁std::cout << "I am a thread process" << ", pid: " << getpid() << std::endl;lock.unlock(); // 解锁sleep(1);}
}int main() 
{pthread_t tid;pthread_create(&tid, nullptr, ThreadRoutine, (void *)"thread 1");while (true) {std::unique_lock<std::mutex> lock(cout_mutex); // 锁定互斥锁std::cout << "I am the main thread" << ", pid: " << getpid() << std::endl;lock.unlock(); // 解锁sleep(1);}return 0;
}

在这里插入图片描述

ps -aL 查看线程

引入线程之后,我们用ps -ajx查不出具体的区别:
在这里插入图片描述这个时候,我们要用ps -aL 查看线程
在这里插入图片描述
上面的LWP(Light Weight Process)就是线程,这里我们看到除了进程的13091,还有一个线程13902属于13901。

线程为什么轻量

线程之所以被称为轻量级进程(Lightweight Process),是因为相比于传统的进程,线程在以下几方面显著地减少了资源消耗和管理开销,从而显得更为轻量:

  1. 共享资源:线程间共享同一个进程的地址空间,包括代码段、数据段以及堆空间。这意味着线程不需要为每个线程复制一份程序代码和全局变量,大大节省了内存资源。
  2. 上下文切换:线程之间的上下文切换比进程更快。因为它们共享同一地址空间,内核在切换时不需要保存和恢复整个地址空间的内容,只需要保存和恢复线程特有的上下文信息,如寄存器状态、栈指针等。
  3. 创建销毁:创建和销毁线程的代价低于进程。由于减少了资源分配的需求,线程的创建速度通常快于进程。同样,销毁线程时,只需释放它独有的资源(如栈空间),而不必回收整个地址空间。
  4. 通信成本:线程间通信更高效。由于共享内存空间,线程可以直接读写同一块内存区域来交换数据,而不需要通过复杂的进程间通信(IPC)机制,如管道、套接字等。
  5. 调度开销:线程的调度通常由同一进程内的线程库或操作系统内核直接管理,而不需要像进程那样涉及更复杂的权限检查和资源分配,因此调度成本较低。

综上所述,线程在资源使用、上下文切换、创建销毁、通信及调度等方面相比进程更加高效,故被形象地称为轻量级进程。这种轻量化使得线程成为实现并发执行、提高程序性能和响应速度的有效手段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/11295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机发展史故事【12】

芯片计算机 众所周知&#xff0c;所谓286、386、486 个人电脑等名称的起源&#xff0c;在于它们采用了英特尔公司研制的微处理器X86 系列芯片286、386 和486。然而&#xff0c;这种以数字为电脑命名的奇特现象&#xff0c;却来源于霍夫博士等人发明的世界上第一个微处理器芯片…

动态路由-链路状态路由协议ospf案例

实验拓扑和要求如图 ospf实验 1.设置各个接口地址 2.测试ar5到ar6的连通性 3.配置ospf协议&#xff0c;routerid&#xff0c;area&#xff0c; 详细的网络信息&#xff0c;等待网络收敛后&#xff0c; 查看ospf信息&#xff0c;路由表信息&#xff0c;再次测试连通性 注意区域…

防火墙技术基础篇:网络地址转换(NAT):防火墙技术的核心机制

防火墙技术基础篇&#xff1a;网络地址转换&#xff08;NAT&#xff09;&#xff1a;防火墙技术的核心机制 网络地址转换&#xff08;NAT&#xff09;是现代网络架构中不可或缺的一个组成部分&#xff0c;尤其在防火墙技术的实现中扮演着重要角色。本文旨在全面解读NAT的工作机…

AI算法-高数5.1-线性代数-向量定义、表示和向量间的关系

看线性代数这篇文章&#xff08;AI算法-高数5-线性代数1-基本概念、向量-CSDN博客&#xff09;理解有些吃力的朋友们&#xff0c;可以先学下宋浩老师的这些课程。 宋浩老师&#xff1a; 3.1 n维向量及其运算_哔哩哔哩_bilibili 3.2 向量间的线性关系&#xff08;一&#xff…

MFC编程之设计美丽的对话框

目录 写在前面&#xff1a; Part 1&#xff1a;美美的设计一下计算器的布局 1.描述文字&#xff1a; ​编辑 2.ID&#xff1a; Part 2&#xff1a;美美熟悉一下计算器的工作流程 Part 3&#xff1a;美美设计一下控件功能 1.edit control&#xff1a; 2.相关变量初始化&…

Agilent MSO9404A、Keysight MSO9404A示波器,4 GHz,4 通道,20 GSa/s

Agilent MSO9404A、Keysight MSO9404A、HP MSO9404A 示波器&#xff0c;4 GHz&#xff0c;4 通道&#xff0c;20 GSa/s Keysight MSO9404A 示波器配备 15 英寸 XGA 显示屏&#xff0c;封装深度仅为 9 英寸&#xff08;23 厘米&#xff09;&#xff0c;重量仅为 26 磅&#xff…

AI地名故事:笔岗村

笔岗村&#xff0c;实际上是由笔村和宏岗村两个古老的村落合并而成的。南宋度宗元年&#xff0c;也就是公元1265年&#xff0c;笔村开始建立。随着时间的推移&#xff0c;到了宋代后期&#xff0c;宏岗村也相继建立。这两个村落各自承载着丰富的历史和文化&#xff0c;最终在历…

铁山靠之数学建模 - Matlab入门

Matlab基础 1. Matlab界面与基本操作1.1 matlab帮助系统1.2 matlab命令1.3 matlab功能符号1.4 matlab的数据类型1.5 函数计算1.6 matlab向量1.7 matlab多项式1.8 M文件1.9 函数文件1.10 matlab的程序结构1.11 echo、warning和error函数1.12 交互输入1.13 程序调试1.14 设置断点…

‌‍‬⁣⁡​⁤⁢​⁢⁡⁣‬‍‌​​‬ ​‍⁤‬ ‬⁡⁡⁡‍‌‬⁡⁡⁢‬⁤⁢⁢⁤​‍‌​​‬ ​⁣‌绘唐3一键追爆款反推软件哪家好

‌‍‬⁣⁡​⁤⁢​⁢⁡⁣‬‍‌​​‬ ​‍⁤‬ ‬⁡⁡⁡‍‌‬⁡⁡⁢‬⁤⁢⁢⁤​‍‌​​‬ ​⁣‌绘唐3一键追爆款反推软件哪家好 支持单镜精绘&#xff0c;可以根据故事情节进行单镜头绘图调整&#xff0c;并支持对SD各类模型的自定义调整。 支持一键完成图文视频合成&am…

Windows11“重置此电脑”后,Edge浏览器在微软应用商店显示“已安装”,但是开始菜单搜索不到的解决办法

Windows11“重置此电脑”后&#xff0c;Edge浏览器在微软应用商店显示“已安装”&#xff0c;但是开始菜单搜索不到的解决办法 为什么重新使用Edge&#xff1f;问题描述不该更新可用更新问过AI&#xff08;通义千问&#xff09;&#xff0c;并且AI提供方法全都无效。现象 操作步…

国产分布式数据库高可用故障检测实现

在分布式数据库架构下&#xff0c;当数据库节点异常时&#xff0c;数据库管理组件能够自动感知到异常并触发节点隔离或者自动切换&#xff0c;是数据库高可用容灾的基本能力。在节点服务器异常、网络异常或进程异常等场景下&#xff0c;各数据库产品本身已经具备了可靠的检测能…

为什么说气膜是环保建筑呢—轻空间

气膜建筑&#xff0c;作为一种绿色环保建筑&#xff0c;其环保特性主要体现在以下几个方面&#xff1a; 1. 节约水资源&#xff1a; 气膜建筑在施工和运行过程中不需要大量水资源&#xff0c;与传统建筑相比&#xff0c;可以每年节约数万吨水资源。这种节约不仅有利于缓解水资源…

【学习AI-相关路程-工具使用-自我学习-Ubuntucudavisco-开发工具尝试-基础样例 (2)】

【学习AI-相关路程-工具使用-自我学习-cuda&visco-开发工具尝试-基础样例 &#xff08;2&#xff09;】 1、前言2、环境说明3、总结说明4、工具安装0、验证cuda1、软件下载2、插件安装 5、软件设置与编程练习1、创建目录2、编译软件进入目录&创建两个文件3、编写配置文…

【iOS开发】—— 初识锁

【iOS开发】—— 初识锁 线程安全锁的种类自旋锁定义原理自旋锁缺点OSSpinLock&#xff08;自旋锁&#xff09; 互斥锁os_unfair_lockpthread_mutexNSLockNSRecusiveLockSemaphore信号量synchronized 总结两种之间的区别和联系&#xff1a; 线程安全 当一个线程访问数据的时候…

Request请求数据 (** kwargs参数)

目录 &#x1f31f;前言&#x1f349;request入门1. params2. data3. json4. headers5. cookies6. auth7. files8. timeout9. proxies10. allow_redirects11. stream12. verify13. cert &#x1f31f;总结 &#x1f31f;前言 在Python中&#xff0c;发送网络请求是一项常见的任…

淘宝商品评论电商API接口,让你购物不再困扰

现在的时代购物已经成为了人们生活中不可或缺的一部分。然而&#xff0c;面对琳琅满目的商品&#xff0c;我们常常犯愁&#xff0c;不知道如何选择。为了解决这个问题&#xff0c;淘宝推出了商品评论电商API接口&#xff0c;为广大消费者提供了极大的便利。联讯数据将详细介绍淘…

数据挖掘实战-基于决策树算法构建银行贷款审批预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

6818Linux内核--Bootloader应用分析

Bootloader应用分析 一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次&#xff1a; 引导加载程序。包括固化在固件( firmware )中的 boot 代码(可选)&#xff0c;和 Boot Loader 两大部分。 Linux 内核。特定于嵌入式板子的定制内核以及内核的启动参数。 文件系统…

一分钟把小程序音频保存到手机上

在这个快节奏的时代&#xff0c;每一分钟都显得格外珍贵。你是否曾在小程序中偶遇一段旋律&#xff0c;它如同清晨的露珠&#xff0c;晶莹剔透&#xff0c;却又转瞬即逝&#xff1f;是否曾在某个瞬间&#xff0c;渴望将那段旋律永久地镌刻在心间&#xff0c;让它成为你私人时光…

【微信小程序开发】flex布局在小程序开发项目中的应用详解

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…