【linux线程(一)】什么是线程?怎样操作线程?
💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:Linux从入门到精通⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学更多操作系统知识
🔝🔝

Linux线程
- 1. 前言
- 2. 什么是线程?
- 3. 线程和进程的区别和联系
- 4. Linux下如何操作线程?
- 5. pthread线程库讲解
- 6. 线程和前面知识的汇总
- 7. 总结以及拓展
1. 前言
可能大家对多线程这三个字早有耳闻,
那么到底什么是线程?为什么要有它?
它和进程之间有什么联系?
本章重点:
本篇文章着重讲解线程的基本概率,
以及进程和线程的对比,最后会讲解
在Linux下如何创建,控制,终止,等待线程
2. 什么是线程?
程序中的一个执行路线就叫做线程
一个进程至少要有一个执行线程,单个进程本身就是一个执行流,所以单个进程某种意义上也是一个线程(是主线程).线程在进程内部运行,本质是在进程地址空间内运行.在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化
在Linux系统下,线程是轻量化的进程,我们知道进程有PCB结构和程序地址空间,那么线程的话只有PCB,它的地址空间是和主线程共享的,如下图:

综上所述,线程就是一个没有独立的地址空间的PCB结构,线程的资源是从最开始的主线程,也就是进程来的.而站在CPU的视角,CPU调度的是PCB结构,CPU只认PCB,它并不关心此PCB是进程的还是线程的,所以线程被称为系统调度的基本单位.而在Linux操作系统下,线程就是轻量化的进程
3. 线程和进程的区别和联系
通过上面对线程的描述,我们可以窥探到:
线程是担任系统调度的基本实体进程是担任系统资源分配的基本实体
虽然线程共享进程数据,但也拥有自己的数据:
- 线程ID
- 栈区资源
- 信号屏蔽字
- 调度优先级

使用指令: ps -al查看线程ID

主线程的PID和LWP相同,CPU调度时是在看LWP,而不是PID,线程的PID和主线程相同,自己独有LWP

4. Linux下如何操作线程?

由于pthred是第三方库
所以编译时要加上-lpthread的字段
如何创建线程

第一个参数需要传入一个pthread_t类型的变量,这个变量我们需要先定义.所谓的pthread_t,实际上本质就是unsigned long int类型,第二个参数我们一般设置为空.第三个参数要传入线程启动后要执行的函数的地址,这个函数的返回值和参数都是void*,最后一个参数是传入给函数形参的,要强转为void*
一般的编码格式:
void *route(void *arg) {while(1) {printf("I'am a thread \n");sleep(1);}
}
int main()
{pthread_t tid;int ret;if ( (ret=pthread_create(&tid, NULL, rout, NULL)) != 0 ) {fprintf(stderr, "pthread_create : %s\n", strerror(ret));exit(-1); //如果创建线程失败会走进此语句}int i;for(; ; ) {printf("I'am main thread\n");sleep(1);}return 0;
}
如何终止线程

一般使用return返回的来终止线程
如何进行线程等待

假如不进行线程等待,可能会出现类似于僵尸进程的问题
一般编码格式:
void *thread_run( void * arg )
{pthread_detach(pthread_self());printf("%s\n", (char*)arg);return NULL;
}
int main( void )
{pthread_t tid;if ( pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0 ) {printf("create thread error\n");return 1;}int ret = 0;sleep(1);//很重要,要让线程先分离,再等待if ( pthread_join(tid, NULL ) == 0 ) {printf("pthread wait success\n");ret = 0;} else {printf("pthread wait failed\n");ret = 1;}return ret;
}
如何进行线程分离
假如创建一个线程后,不想关心它的返回值,此时使用join等待实际上是一种负担,所以使用线程分离后,可以把创建的线程和主线程分离,这样就不会影响到主线程

pthread_self()函数可以返回当前线程的线程ID,所以假设我们想要当前线程与主线程脱离关系,可以这样写: pthread_detach(pthread_self());
一般编码格式:
void *thread_run( void * arg )
{pthread_detach(pthread_self());printf("%s\n", (char*)arg);return NULL;
}
int main( void )
{pthread_t tid;if ( pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0 ) {printf("create thread error\n");return 1;}int ret = 0;sleep(1);//很重要,要让线程先分离,再等待if ( pthread_join(tid, NULL ) == 0 ) {printf("pthread wait success\n");ret = 0;} else {printf("pthread wait failed\n");ret = 1;}return ret;
}
5. pthread线程库讲解
首先,pthread_create的返回值是线程ID.
那么线程ID的本质是什么呢?
答案是,线程ID的本质是一个地址,pthread库是一个动态库,是第三方库,这个库会被映射到进程的地址空间的共享区中,而线程ID所指的地址则是pthread这个库层面上,线程集合的起始地址

再回忆一下刚才的内容,线程有自己的栈区,也就是说线程要维护自己的栈区,那么可以联想一下,谁帮线程维护这个栈区呢?答案是pthread库维护的栈区,也就是说其实线程的栈区也是被映射到共享区的,由pthread第三方库维护
6. 线程和前面知识的汇总
这里有三个问题要思考一下:
- 线程异常退出后,主线程也会退出吗?
- 线程可以用fork创建子进程吗?
- 线程可以进行进程程序替换吗?
第一个问题
一个进程(主线程)可以拥有多个线程,这多个线程只要其中一个线程发生错误,导致此线程退出,那么所有的线程包括主线程都会退出.所以在编写线程函数时,一定要多加小心
第二个问题
线程可以通过函数fork来创建子进程,并且在实际运用中是有被使用到的实例
第三个问题
线程不能进行进程程序替换,因为线程是共用主线程的资源,一旦一个线程进行进程程序替换后,所有的线程包括主线程的代码都会被替换为别的程序,这显然是不正确的
7. 总结以及拓展
最后,创建线程有优点也有缺点,在实际
编写代码中大家根据自己的需求来定


在某些多线程的场景下,执行一段代码可能会出现不一样的结果,这就是线程的安全问题,关于线程的安全问题以及线程互斥和线程同步的概率会在下一篇文章讲解
相关文章:
【linux线程(一)】什么是线程?怎样操作线程?
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Linux从入门到精通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多操作系统知识 🔝🔝 Linux线程 1. 前言2. 什么是线…...
python-0002-linux安装pycharm
下载软件包 下载地址:https://download.csdn.net/download/qq_41833259/88944791 安装 # 解压 tar -zxvf 你的软件包 # 进入软件解压后的路径,如解压到了/home/soft/pycharm cd /home/soft/pycharm cd bin # 执行启动命令 sh pycharm.sh # 等待软件启…...
扭蛋机小程序,扭蛋与互联网结合下的商机
扭蛋机作为一种娱乐消费模式,受众群体不再局限于儿童,也吸引了众多的年轻消费者。扭蛋机具有较大的随机性,玩具商品随机掉落,在购买前消费者完全不知道扭蛋中的商品是什么,这种未知性带来的惊喜感是吸引众多消费者的主…...
pytorch CV入门3-预训练模型与迁移学习
专栏链接:https://blog.csdn.net/qq_33345365/category_12578430.html 初次编辑:2024/3/7;最后编辑:2024/3/8 参考网站-微软教程:https://learn.microsoft.com/en-us/training/modules/intro-computer-vision-pytorc…...
Swift SwiftUI 学习笔记 2024
Swift SwiftUI 学习笔记 2024 一、资源 视频资源 StanfordUnivercity 公开课 2023: https://cs193p.sites.stanford.edu/2023 教程 Swift 初识:基础语法:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/…...
【Stable Diffusion】入门:原理简介+应用安装(Windows)+生成步骤
【Stable Diffusion】入门:原理简介应用安装(Windows)生成步骤 原理简介应用安装 原理简介 稳定扩散生成模型(Stable Diffusion)是一种潜在的文本到图像扩散模型,能够在给定任何文本输入的情况下生成照片般逼真的图像。 应用安…...
【栈】第十二届蓝桥杯省赛第一场C++ B组/研究生组《双向排序》(c++)
【题目描述】 给定序列 (a1,a2,⋅⋅⋅,an)(1,2,⋅⋅⋅,n),即 aii。 小蓝将对这个序列进行 m 次操作,每次可能是将 a1,a2,⋅⋅⋅,aqi 降序排列,或者将 aqi,aqi1,⋅⋅⋅,an 升序排列。 请求出操作完成后的序列。 【输入格式】 输入的第一行…...
Gitea 安装和配置
Gitea 安装和配置: http://coffeelatte.vip.cpolar.top/post/software/applications/gitea/gitea_安装和配置/ 文章目录 Gitea 安装和配置: <http://coffeelatte.vip.cpolar.top/post/software/applications/gitea/gitea_%E5%AE%89%E8%A3%85%E5%92%8C%E9%85%8D%E7%BD%AE/>…...
CEF JS与c++能够交互的原理 以及 JS 调用C++的流程分析
相关章节:CEF 之 Render进程 与 Browser进程通信 目录 一、JS与c++能够交互的原理 二、JS调用C++ 流程梳理...
关于比特币的AI对话
【ChatGPT】 比特币源码开源吗? 是的,比特币的源码是开源的。比特币项目是在MIT许可证下发布的,这意味着任何人都可以查看、修改、贡献和分发代码。比特币的源码托管在GitHub上,可以通过下面的链接进行访问: https://g…...
Linux查看磁盘命令df-h详解
df -h 是一个常用的 Linux 命令,用于查看文件系统的磁盘使用情况并以易于阅读的方式显示。以下是 df -h 命令的详细解释: -h:以人类可读的格式显示磁盘空间大小。例如,使用 GB、MB、KB 等单位代替字节。 执行 df -h 命令后&…...
nginx-排查一次大文件无法正常下载问题
目录 问题现象&报错信息 问题现象以及分析 nginx报错信息 问题解决 方法1:配置proxy_max_temp_file_size 方法2:关闭proxy_buffering 参考文档 问题现象&报错信息 问题现象以及分析 文件正常从后端服务器直接下载时,一切正常…...
基于yolov5的草莓成熟度检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】
功能演示: 基于yolov5的草莓成熟度检测系统,系统既能够实现图像检测,也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili (一)简介 基于yolov5的草莓成熟度系统是在pytorch框架下实现的,这是一个完整的项目…...
Kubesphere 保姆级分析
应用场景 KubeSphere 适用于多种场景,为企业提供容器化的环境,借助完善的管理和运维功能,让企业在数字化转型过程中从容应对各种挑战和各类业务场景,如多云多集群管理、敏捷软件开发、自动化运维、微服务治理、流量管理以及 DevO…...
力扣hot100:240.搜索二维矩阵II(脑子)
吉大21级算法分析与设计的一道大题,由于每一行都是排好序的直接逐行二分 可以达到:O(mlogn)。但是这里追求更广的思路可以使用其他方法。 矩阵四分: 在矩阵中用中心点比较,如果target大于中心点的值,则由于升序排列&am…...
Apache Hive(三)
一、Apache Hive 1、ETL数据清洗 数据问题 问题1:当前数据中,有一些数据的字段为空,不是合法数据 解决:where 过滤 问题2:需求中,需要统计每天、每个小时的消息量,但是数据中没有天和小时字段…...
ORM(对象关系映射)的概念,并说明在Python中如何使用
ORM(对象关系映射)的概念,并说明在Python中如何使用 ORM(对象关系映射)是一种编程技术,它实现了将关系型数据库中的数据映射到程序中的对象模型,使得开发者能够使用面向对象的方式来操作数据…...
Br 算法
基于google的brotli开源,实现Br算法。 #include <brotli/encode.h> #include <brotli/decode.h>namespace br {/*compress unsigned char* content,if ok return non empty unsigned char * */std::string compress_string(const std::string& c…...
GPT实战系列-一种构建LangChain自定义Tool工具的简单方法
GPT实战系列-一种构建LangChain自定义Tool工具的简单方法 LLM大模型: GPT实战系列-探究GPT等大模型的文本生成 GPT实战系列-Baichuan2等大模型的计算精度与量化 GPT实战系列-GPT训练的Pretraining,SFT,Reward Modeling,RLHF …...
【Docker】Memcached 容器化部署
Memcached环境标准软件基于Bitnami Memcached 构建。当前版本为1.6.24 你可以通过轻云UC部署工具直接安装部署,也可以手动按如下文档操作,该项目已经全面开源,可以从如下环境获取 配置文件地址: https://gitee.com/qingplus/qingcloud-platf…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
