【面试八股总结】线程基本概念,线程、进程和协程区别,线程实现
一、什么是线程?
线程是“轻量级进程”,是进程中的⼀个实体,是程序执⾏的最小单元,也是被系统独立调度和分配的基本单位。
线程是进程当中的⼀条执行流程,同⼀个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有⼀套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。

二、线程的优缺点
线程的优点:
- 一个进程中可以同时存在多个线程;
- 各个线程之间可以并发执行;
- 各个线程之间可以共享地址空间和文件等资源;
线程的缺点:
- 当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃
三、进程、线程和协程区别
| 进程 | 线程 | 协程 | |
| 定义 | 资源分配和拥有的基本单位 | 程序执行的基本单位 | 用户态的轻量级线程 |
| 切换情况 | 保存和设置进程CPU环境(栈、寄存器、页表和文件句柄) | 保存和设置程序计数器、少量寄存器和栈 | 先将寄存器上下文和栈保存,等切换回来的时候再进行恢复 |
| 切换者 | 操作系统 | 操作系统 | 用户 |
| 切换过程 | 用户态->核心态->用户态 | 用户态->核心态->用户态 | 用户态 |
| 调用栈 | 内核栈 | 内核栈 | 用户栈 |
| 拥有资源 | CPU资源、内存资源、文件资源和句柄等 | 程序计数器、寄存器、栈和状态字 | 拥有自己的寄存器上下文和栈 |
| 并发性 | 不同进程之间切换实现并发,各自占有CPU实现并行 | 一个进程内部的多个线程并发执行 | 同一时间只能执行一个协程,其他协程处于休眠状态,适合对任务进行分时处理 |
| 系统开销 | 切换虚拟机地址空间,切换内核栈和硬件上下文,开销大 | 切换时只需保存和设置很少量的寄存器内容,开销小 | 直接操作栈,基本没有内核切换开销,可以不加锁的访问全局变量,上下文切换速度非常快 |
| 通信方面 | 需要借助操作系统(管道、消息队列、共享内存、内存映射、信号量、信号、Socket) | 直接读写进程数据段(eg.全局变量)进行通信 | 共享内存、消息队列 |
四、线程实现
1. 线程创建和结束
- 一般情况下,main函数所在的线程我们称之为主线程(main线程),其余创建的线程称之为子线程。 程序中默认只有一个线程,调用pthread_create()函数产生新的线程。
// 创建线程
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失败:返回错误号。这个错误号和之前errno不太一样。获取错误号的信息: char * strerror(int errnum);
- 获得线程id :pthread_self
pthread_t pthread_self(void);
- 等待线程结束:pthread_join,主线程调⽤,等待子线程退出并回收其资源,类似于进程中wait/waitpid回收僵尸进程,调用 pthread_join的线程会被阻塞
int pthread_join(pthread_t thread, void **retval);- 功能:和一个已经终止的线程进行连接回收子线程的资源- 特点:这个函数是阻塞函数,调用一次只能回收一个子线程一般在主线程中使用- 参数:- thread:需要回收的子线程的ID- retval: 接收子线程退出时的返回值- 返回值:0 : 成功非0 : 失败,返回的错误号
- 结束线程: 子线程执行,用于结束当前线程并通过retval传递返回值,该返回值可通过pthread_join获得
void pthread_exit(void *retval);功能:终止一个线程,在哪个线程中调用,就表示终止哪个线程参数:retval:需要传递一个指针,作为一个返回值,可以在pthread_join()中获取到。
- 分离线程:主线程、子线程均可调⽤。主线程中pthread_detach(tid),子线程中 pthread_detach(pthread_self()),调⽤后和主线程分离,子线程结束时自己立即回收资源
int pthread_detach(pthread_t thread);- 功能:分离一个线程。被分离的线程在终止的时候,会自动释放资源返回给系统。1. 不能多次分离,会产生不可预料的行为。2. 不能去连接一个已经分离的线程,会报错。- 参数:需要分离的线程的ID- 返回值:成功:0失败:返回错误号
2. 线程属性
线程属性对象类型为pthread_attr_t,结构体定义如下:
typedef struct{int detachstate; // 线程分离的状态int schedpolicy; // 线程调度策略struct sched_param schedparam; // 线程的调度参数int inheritsched; // 线程的继承性int scope; //线程的作用域//以下为线程栈的设置size_t guardsize; //线程栈末尾警戒缓冲大小int stackaddr_set; // 线程的栈设置void * stackaddr;// 线程栈的位置size_t stacksize;//线程栈大小
}pthread_attr_t;
设置线程属性相关函数:int pthread_attr_init(pthread_attr_t *attr);- 初始化线程属性变量int pthread_attr_destroy(pthread_attr_t *attr);- 释放线程属性的资源int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);- 获取线程分离的状态属性int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);- 设置线程分离的状态属性相关文章:
【面试八股总结】线程基本概念,线程、进程和协程区别,线程实现
一、什么是线程? 线程是“轻量级进程”,是进程中的⼀个实体,是程序执⾏的最小单元,也是被系统独立调度和分配的基本单位。 线程是进程当中的⼀条执行流程,同⼀个进程内多个线程之间可以共享代码段、数据段、打开的文件…...
Java核心技术【二十】Java泛型的基本概念和原理详解
Java泛型的基本概念和原理详解 一、泛型的基本概念 Java泛型(Generics)是Java SE 1.5(JDK 5)引入的一个新特性,它提供了一种在编译时期进行类型检查的方式,允许程序员在定义类、接口和方法时指定类型参数…...
Android Studio Download Gradle 时慢问题解决
1.腾讯gradle 下载:后面拼接版本(gradle-8.0-bin.zip) https://mirrors.cloud.tencent.com/gradle/gradle-8.0-bin.zip 2.Android Studio 配置:setting-->gradle-->Use Gradle from 选择本地文件夹(解压后的bi…...
【Qt5】入门Qt开发教程,一篇文章就够了(详解含qt源码)
目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范 2.5 QtCreator常用快捷键 三、Qt按钮小程序 …...
阿里MotionShop——AI视频工具:一键替换视频人物为3D虚拟角色~
近期AI相关的新奇应用层出不穷,今天小元老师要给大家安利一个由阿里巴巴研发的AI视频生成技术——MotionShop! 1、一键替换3D虚拟角色 MotionShop通过视频处理、角色检测、背景修复等多重步骤,能够将视频中的人物角色,一键转换成…...
Jetpack Compose实战教程(五)
Jetpack Compose实战教程(五) 第五章 如何在Compose UI中使用基于命令式UI的自定义View 文章目录 Jetpack Compose实战教程(五)一、前言二、本章目标三、开始编码3.1 先让自定义控件能跑起来3.2给自定义控件使用compose的方式赋值…...
【vueUse库Watch模块各函数简介及使用方法--上篇】
vueUse库是一个专门为Vue打造的工具库,提供了丰富的功能,包括监听页面元素的各种行为以及调用浏览器提供的各种能力等。其中的Browser模块包含了一些实用的函数,以下是这些函数的简介和使用方法: vueUse库Sensors模块各函数简介及使用方法 vueUseWatch函数1. until2. watc…...
JavaScript中的LHS和RHS
LHS和RHS之前我们先来回忆一下最简单的赋值操作! var test100; console.log(test); 以上代码的意思简单我们理解为把右边的值赋值给左边的test变量,然后输出打印结果。 可是我们要是深入理解你就会发现在这个过程当中,还发生了一些其他的事情 而这些事情就是今天…...
appium 实战问题 播放视频时无法定位到元素
背景 在做UI自动化时,有播放详情页的用例,但是发现视频在播放的时候无法定位到元素或者很慢,了解到appium在动态的页面实时获取布局元素导致定位变慢。所以只能将视频暂停在操作元素,点击到暂停按钮又是个问题,通过ad…...
鸿蒙‘ohpm‘ 不是内部或外部命令,也不是可运行的程序-解决方案
🔥 博客主页: 小韩本韩! ❤️ 感谢大家点赞👍收藏⭐评论✍️ 在鸿蒙的DevEco Studio的终端下输入 ohpm -v 或者 你需要下载第三方ohpm包的时候提示‘ohpm‘ 不是内部或外部命令,也不是可运行的程序- 主要是因为我们…...
方法引用 异常 file
目录 一.方法引用 1.方法引用概述 2.引用静态方法 3.引用成员方法 i.引用其他成员方法 ii.引用本类成员方法 iii.引用父类成员方法 4.引用构造方法 5.其他调用方式 i.使用类名引用成员方法 ii.引用数组的构造方法 二、异常 1.异常的作用 2.异常的处理方式 i.JVM…...
比较(六)利用python绘制径向柱图
比较(六)利用python绘制径向柱图 径向柱图(Circular Barplot)简介 径向柱图基于同心圆网格来绘制条形图,虽然不如普通条形图表达准确,但却有抓人眼球的效果。其衍生的南丁格尔玫瑰图则广为人知。 快速绘制…...
为什么需要重写equals和如何重写equals
首先先看Java中的 ,比较的两个对象的地址值。 如果是基本数据类型,那么就是比较的是值。 如果是引用数据类型,比较的就是地址. object类中的equals方法也是用的; 所以要比较两个对象的大小,去调用默认的equals方法…...
C#字符串操作:判断一个字符串是否存在于另一个字符串按特定字符分割后的子字符串中的几种方法
要判断一个字符串是否存在于另一个字符串按特定字符分割后的子字符串中,可以使用以下几种方法: 方法一:使用Split和Array.Exists 你可以使用 Split 方法将字符串分割成子字符串数组,然后使用 Exists方法检查目标字符串是否在数组…...
Hi3861 OpenHarmony嵌入式应用入门--MQTT
MQTT 是机器对机器(M2M)/物联网(IoT)连接协议。它被设计为一个极其轻量级的发布/订阅消息传输 协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、 高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器…...
[22] Opencv_CUDA应用之 使用背景相减法进行对象跟踪
Opencv_CUDA应用之 使用背景相减法进行对象跟踪 背景相减法是在一系列视频帧中将前景对象从背景中分离出来的过程,它广泛应用于对象检测和跟踪应用中去除背景 背景相减法分四步进行:图像预处理 -> 背景建模 -> 检测前景 -> 数据验证 预处理去除噪声背景建模,以便与…...
Maven在Windows中的配置方法
本文介绍在Windows电脑中,下载、配置Maven工具的详细方法。 Maven是一个广泛使用的项目管理工具,主要针对Java项目,但也可以用于其他类型的项目;其由Apache软件基金会维护,旨在简化和标准化项目构建过程,依…...
一、redis-万字长文读懂redis
高性能分布式缓存Redis `第一篇章`1.1缓存发展史&缓存分类1.1.1 大型网站中缓存的使用带来的问题1.1.2 常见缓存的分类及对比与memcache对比1.2 数据类型选择&应用场景1.2.1 string1.2.2 hash1.2.3 链表1.2.4 set1.2.5 sortedset有序集合类型1.2.6 总结1.3 Redis高级应…...
搞清楚[继承],易如反掌
穷不失义,达不离道。——孔丘《论语》 继承 1、简单理解2、继承2、1、继承的概念2、2、继承定义2、3、基类和派生类对象赋值转换2、4、继承中的作用域2、5、派生类默认成员函数2、6、继承中的特点2、6、1、友元2、6、2、静态成员2、6、3、菱形继承及菱形虚拟继承 3、…...
Perl 语言入门学习指南:探索高效脚本编程的奥秘
引言 Perl,全称Practical Extraction and Report Language,是一种功能强大的编程语言,特别擅长于文本处理、报告生成以及系统自动化管理任务。自1987年诞生以来,Perl凭借其灵活性、强大的内置功能库和广泛的社区支持,…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
