Linux - 什么是线程和线程的操作
线程概念
什么是线程:
线程(Thread)是操作系统能够进行运算调度的最小单位. 它被包含在进程之中, 是进程中的实际运作单位. 一个进程可以包含多个线程.
进程 : 线程 == 1 : n (n >= 1).
进程是系统分配资源的基本单位.
线程则是系统调度的基本单位.
在 Linux 中, 线程又被称为轻量级进程. 因为线程不必再进行空间的分配. 只需要对新创建的线程进行初始化 (创建线程的PCB即可).
可以看到, 如果要新建线程, 只需要创建相应的 线程控制块(TCB) 即可, TCB 和 PCB中的内容非常相近.
在 Linux 中是没有单独实现线程的. Linux 中的线程都是通过进程来实现的.
所以在 Linux 实际上是没有线程的, 站在调度的视角来看, 调度的都是进程不存在线程.
线程与进程区别
1. 进程是系统资源分配的基本单位
2. 线程是系统调度的基本单位
虽然线程共享进程的资源, 但是每个进程也都会有只属于自己的数据和资源.
- 线程ID
- 每个线程都有独属于自己的栈空间
- 既然线程是调度的基本单位,那每个线程的调度优先级也有可能是不同的
线程共享的如: 代码段, 全局变量, 信号的处理 ....
可以使用指令: ps -L. 来查看所有的进程和线程
LWP 就是线程ID. PID 和 LWP 相同的线程就是这个进程的主线程
PID 相同的线程则属于同一个进程.
如何操作线程
上面提到了, Linux 系统本身没有为线程单独实现, 但是提供了一个第三方库: <pthread>.
使用 <pthread> 库就能在 Linux 下完成线程的操作.
因为这个库是第三方库, 所以在使用时, 使用G++编译时需要加入选项 "-lpthread"
g++ -o text.exe test.cpp -lpthread
创建线程
了解 pthread_create 函数:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
// thread:指向 pthread_t 类型的指针, 用于存储新创建的线程ID.
// attr:指向 pthread_attr_t 类型的指针, 用于设置线程属性. 通常传 NULL 表示使用默认属性.
// start_routine:线程函数的指针.
// arg:传递给线程函数的参数.
创建线程的例子:
#include<pthread.h>
void* func(void* args)
{printf("thread func running\n");return NULL;
}
int main()
{pthread_t thread; // 用来记录创建出来的线程的线程IDret = pthread_create(&thread, NULL, func, NULL); // 创建线程if(ret != 0){perror("创建线程失败");return 1;}pthread_join(thread, NULL); // 和进程一样, 创建了子进程后, 需要等待子进程结束// 这里同样需要等待线程结束return 0;
}
在上面的代码中, 将线程创建出来后, 线程就会独立的去运行 func 函数, 当 func 函数结束时, 线程也同样结束了. 线程只会运行传给他的函数.
线程终止
1. return 返回
在上面的例子中, 我们等待创建出来的线程运行到末尾, 执行 return 语句.
执行完 return 语句后, 线程就结束了.
2. 使用函数 pthread_exit()
pthread_exit
函数可以立即终止当前线程, 并返回指定的值.
#include<pthread.h>
void* func(void* arg)
{printf("thread is running\n");pthread_exit(); // 线程执行这一句后, 本线程就会被终止printf("no running\n");
}
3. 使用 pthread_cancel() 函数
void* func(void* arg)
{}
int main()
{pthread_t thread;if (pthread_create(&thread, NULL, func, NULL) != 0) {perror("pthread_create");return 1;}// 请求终止线程if (pthread_cancel(thread) != 0) // 将线程的 ID 传给函数{perror("pthread_cancel");return 1;}return 0;
}
以上三种方法在线程终止后, 都可以通过 pthread_join() 函数进行线程等待.
int pthread_join(pthread_t thread, void **retval);
thread
:要等待的线程的 ID. 这个 ID 是通过pthread_create
函数创建线程时返回的.
retval
:指向void *
类型的指针, 用于存储线程函数的返回值. 如果不需要获取线程的返回值, 可以传NULL.
pthread_join()
等待线程终止后, 会自动释放线程的资源. 如果线程没有被等待, 其资源会在线程终止时自动释放, 但可能会导致资源泄漏.
线程分离
如果我们并不关心线程的运行情况, 我们也可以选择不进行线程等待, 这个线程在运行结束后, 就会自动释放资源, 不需要我们调用 pthread_join() 函数.
我们需要将线程设置为分离状态, 这样主线程就不用调用 pthread_join().
int pthread_detach(pthread_t thread);
#include <pthread.h>void* thread_function(void* arg)
{// 线程要执行的代码printf("Thread function is running.\n");return NULL;
}int main()
{pthread_t thread;// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0){perror("pthread_create");return 1;}// 将线程设置为分离状态if (pthread_detach(thread) != 0){perror("pthread_detach");return 1;}// 主线程继续执行printf("Main thread is running.\n");// 将上面创建的线程设置为分离状态后, 就不用调用 pthread_join 函数.return 0;
}
线程优缺点
-
优点:
- 提高程序的响应性和并行处理能力
- 共享内存, 减少资源开销
- 轻量级, 调度开销小
- 适合细粒度的并发任务
-
缺点:
- 数据竞争和同步问题复杂
- 容易发生死锁, 难以检测和解决
- 线程管理开销, 创建和销毁线程消耗资源
- 优先级问题, 可能导致优先级倒置和调度不公平
相关文章:

Linux - 什么是线程和线程的操作
线程概念 什么是线程: 线程(Thread)是操作系统能够进行运算调度的最小单位. 它被包含在进程之中, 是进程中的实际运作单位. 一个进程可以包含多个线程. 进程 : 线程 1 : n (n > 1). 进程是系统分配资源的基本单位. 线程则是系统调度的基本单位. 在…...
windows及linux 安装 Yarn 4.x 版本
1. 确保系统环境准备 a. 安装 Node.js Yarn 依赖于 Node.js,所以需要先安装 Node.js。前往 Node.js 官网 下载并安装适合你的 Windows 版本的 Node.js(推荐 LTS 版本)。安装完成后,打开命令提示符(CMD)或 PowerShell,验证安装:node -v npm -v如果显示版本号,则表示安…...

如何设计一个 RPC 框架?需要考虑哪些点?
面试官:如何设计一个 RPC 框架?需要考虑哪些点? 设计一个远程过程调用(RPC)框架是一个复杂的系统工程,涉及多个方面的考虑。一个好的 RPC 框架应具备可扩展性、灵活性、易用性和高性能。下面是设计 RPC 框…...

初学stm32 --- DAC输出三角波和正弦波
输出三角波实验简要: 1,功能描述 通过DAC1通道1(PA4)输出三角波,然后通过DS100示波器查看波形 2,关闭通道1触发(即自动) TEN1位置0 3,关闭输出缓冲 BOFF1位置1 4,使用12位右对齐模式 将数字量写入DAC_…...
开源cJson用法
cJSON cJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。 cJSON项目托管在Github上,仓库地址如下: https://github.com/DaveGamble/cJSON 使用Git命令将其拉…...
【学习笔记】理解深度学习和机器学习的数学基础:数值计算
深度学习作为人工智能领域的一个重要分支,其算法的实现和优化离不开数值计算。数值计算在深度学习中扮演着至关重要的角色,它涉及到如何在计算机上高效、准确地解决数学问题。本文将介绍深度学习中数值计算的一些关键概念和挑战,以及如何应对…...

如何使用CSS让页面文本两行显示,超出省略号表示
talk is cheap, show me the code 举个栗子,如下: <span class"a">我说说<b class"b">打瞌睡党风建设打火机</b>说说色儿</span>a{display:block/inline-block;width:100px;overflow: hidden; white-spac…...

likeshop同城跑腿系统likeshop回收租赁系统likeshop多商户商城安装及小程序对接方法
前言:首先likeshop是一个开发平台,是一个独创的平台就像TP内核平台一样,你可以在这个平台上开发和衍生出很多伟大的产品,以likeshop为例,他们开发出商城系统,团购系统,外卖点餐系统,…...
C# 与 Windows API 交互的“秘密武器”:结构体和联合体
一、引言 在 C# 的编程世界里,当我们想要深入挖掘 Windows 系统的底层功能,与 Windows API 打交道时,结构体和联合体就像是两把神奇的钥匙🔑 它们能够帮助我们精准地操控数据,实现一些高级且强大的功能。就好比搭建一…...
PHP 使用 Redis
PHP 使用 Redis PHP 是一种广泛使用的服务器端编程语言,而 Redis 是一个高性能的键值对存储系统。将 PHP 与 Redis 结合使用,可以为 Web 应用程序提供快速的读写性能和丰富的数据结构。本文将详细介绍如何在 PHP 中使用 Redis,包括安装、连接、基本操作以及一些高级应用。 …...
嵌入式系统Linux实时化(四)Xenomai应用开发测试
1、Xenomai 原生API 任务管理 Xenomai 本身提供的一系列多任务调度机制,主要有以下一些函数: int rt_task_create (RT_TASK task, const char name, int stksize, int prio, intmode) ; 任务的创建;int rt_task_start(RT_TASK task, void(entry)(void cookie), void cookie…...

26个开源Agent开发框架调研总结(2)
根据Markets & Markets的预测,到2030年,AI Agent的市场规模将从2024年的50亿美元激增至470亿美元,年均复合增长率为44.8%。 Gartner预计到2028年,至少15%的日常工作决策将由AI Agent自主完成,AI Agent在企业应用中…...
Element UI与Element Plus:深度剖析
文章目录 前言一、概述二、技术特性三、设计理念四、使用体验五、迁移指南结语 前言 随着前端开发技术的快速发展,Vue.js 生态系统中的组件库也在不断进化。Element UI 和 Element Plus 是两个深受开发者喜爱的 Vue 组件库,它们分别构建于 Vue 2.x 和 V…...

二、BIO、NIO编程与直接内存、零拷贝
一、网络通信 1、什么是socket? Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口,一般由操作 系统提供。客户端连接上一个服务端,就会在客户端中产生一个 socket 接口实例,服务端每接受 一个客户端…...
VSCode 更好用的设置
配置 {"terminal.integrated.fontSize": 15,"security.workspace.trust.untrustedFiles": "open","editor.minimap.enabled": false,"workbench.colorTheme": "Visual Studio 2017 Light - C","gnuGlobal.c…...

【git】-3 github创建远程仓库,上传自己的项目,下载别人的项目
一、如何使用Github 1、创建远程仓库 2、使用github拉取/推送代码 克隆仓库 向远程仓库推送代码-git push 二、上传我们自己的项目到github 方法一:直接上传 方法二:使用git命令 方法三: 将仓库拉取到本地上传 三、下载别人的项目 …...

计算机组成原理(1)
系统概述 计算机硬件基本组成早期冯诺依曼机现代计算机 计算机各部分工作原理主存储器运算器控制器计算机工作过程 此文章的图片资源获取来自于王道考研 计算机硬件基本组成 早期冯诺依曼机 存储程序是指将指令以二进制的形式事先输入到计算机的主存储器,然后按照…...

Openstack网络组件之Neutron
从Nova到Neutron:OpenStack网络架构的演变 在云计算和虚拟化技术迅猛发展的背景下,OpenStack 成为了构建私有云和公有云平台的首选解决方案之一。早期版本中,Nova 项目不仅负责计算资源的管理,还承担了提供基本网络连接的任务。然…...
神州数码交换机和路由器命令总结
神州数码交换机和路由器命令总结 一、神州数码交换机命令总结 1. 交换机恢复出厂设置及其基本配置. 1) //进入特权模式 2) del startup.cfg 2. Telnet方式管理交换机. 1) //进入全局配置模式 2) enable password 0 [密码] 3) Line 0 4 4) Password 0 [密码] 5) Login 3. 交换机…...

Spring MVC简单数据绑定
【图书介绍】《SpringSpring MVCMyBatis从零开始学(视频教学版)(第3版)》_springspringmvcmybatis从零开始 代码、课件、教学视频与相关软件包下载-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)(第3版&…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...
Python爬虫(四):PyQuery 框架
PyQuery 框架详解与对比 BeautifulSoup 第一部分:PyQuery 框架介绍 1. PyQuery 是什么? PyQuery 是一个 Python 的 HTML/XML 解析库,它采用了 jQuery 的语法风格,让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...