线程与进程的深入解析及 Linux 线程编程
在操作系统中,进程和线程是进行并发执行的两种基本单位。理解它们的区别和各自的特点,能够帮助开发者更好地进行多任务编程,提高程序的并发性能。本文将探讨进程和线程的基础概念,及其在 Linux 系统中的实现方式,并介绍如何在 Linux 下进行线程编程。
进程与线程概念
进程
进程是程序的执行实例,是操作系统进行资源分配和调度的基本单位。每个进程都具有自己的独立内存空间、程序计数器、堆栈等资源。进程的创建过程是通过复制当前进程的数据来完成的,常见的系统调用有 fork() 和 vfork():
fork():创建一个子进程,子进程是父进程的副本,拥有独立的内存空间。父进程和子进程的资源相互隔离。vfork():创建一个子进程时,父进程会被暂停,子进程共享父进程的内存空间,直到子进程调用exec()或_exit()来退出。
然而,进程的创建通常涉及大量的数据复制,影响系统的效率。这是因为每个进程都需要有独立的资源,造成一定的开销。
线程
线程是进程中的执行单位,也是操作系统调度的最小单位。与进程不同,线程不拥有独立的资源,而是与同一进程中的其他线程共享进程的资源(如内存、文件描述符等)。线程的创建和销毁比进程更加轻量级,因此线程通常用于提高并发性能。
一个线程通常由以下几个部分组成:
- 线程ID (Thread ID):每个线程都有一个唯一的标识符。
- 程序计数器:指向线程执行的下一条指令。
- 寄存器:保存线程执行的中间状态。
- 栈:每个线程有自己的栈,用于保存局部变量和函数调用的上下文。
进程与线程的关系
- 线程依附于进程:每个线程都属于某个进程,不能脱离进程独立存在。
- 进程终止,线程随之终止:当一个进程终止时,其内部所有的线程都会被终止。
- 一个进程可以创建多个线程:这使得进程内可以同时执行多个任务,从而提高并发度。
进程与线程的区别
-
资源分配:
- 进程是资源分配的单位,每个进程都有独立的资源。
- 线程是调度执行的单位,多个线程共享同一进程的资源。
-
创建开销:
- 进程创建时需要复制大量数据,开销较大。
- 线程创建轻量级,开销较小。
-
调度单位:
- 进程是操作系统调度的基本单位。
- 线程是操作系统调度的最小单位。
Linux 下的线程编程
在 Linux 系统中,线程编程通常依赖于 NPTL(Native POSIX Thread Library),这是一种本地线程库,实现了 POSIX 标准中的线程相关接口。NPTL 库提供了线程的创建、执行、结束等功能。
创建线程
Linux 中可以通过 pthread_create 函数创建线程。该函数的原型如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void *), void *arg);
thread:线程的标识符。attr:线程属性,一般为NULL表示使用默认属性。start_routine:线程执行的函数(即线程的入口函数)。arg:传递给start_routine函数的参数。
线程的执行函数通常定义如下:
void *do_something(void *arg) {printf("Thread %d\n", getpid());return NULL;
}
创建线程后,主线程和新创建的线程将并发执行。
线程的结束
线程可以通过以下几种方式结束:
- 返回:线程执行函数返回时,线程结束,等价于调用
pthread_exit。 - 调用
pthread_exit:主动调用pthread_exit结束线程。 - 线程被取消:通过
pthread_cancel可以取消线程。 - 进程结束:如果进程结束,所有线程也会结束。
void pthread_exit(void *retval);
retval:线程退出时传递的返回值。
线程同步
线程共享进程的资源,这带来了数据竞争问题。为了避免多个线程同时访问共享数据导致的错误,我们通常使用互斥锁(mutex)等同步机制。
例如,可以使用 pthread_mutex_lock 和 pthread_mutex_unlock 来保护临界区:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void *thread_func(void *arg) {pthread_mutex_lock(&mutex);// 临界区代码pthread_mutex_unlock(&mutex);return NULL;
}
线程终止与回收
当一个线程结束时,其资源不会立即释放。如果需要主线程等待某个子线程结束并回收其资源,可以使用 pthread_join:
int pthread_join(pthread_t thread, void **retval);
thread:要等待的线程。retval:线程的返回值。
pthread_join 会阻塞当前线程,直到指定的线程结束。
示例代码
以下是一个简单的示例,展示如何在 Linux 下创建多个线程,分别打印不同的消息:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>void *thread1_func(void *arg) {printf("Thread 1: PID = %d\n", getpid());return NULL;
}void *thread2_func(void *arg) {printf("Thread 2: PID = %d\n", getpid());return NULL;
}int main() {pthread_t thread1, thread2;pthread_create(&thread1, NULL, thread1_func, NULL);pthread_create(&thread2, NULL, thread2_func, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);return 0;
}
查看全部
编译时,使用 -lpthread 链接线程库:
gcc -o thread_example thread_example.c -lpthread
结论
进程和线程是操作系统中的两种基本单位,它们在资源管理和调度上各有不同。进程是资源分配的单位,而线程是调度的基本单位。在 Linux 中,NPTL 库提供了高效的线程创建和管理方式,线程编程能够显著提高程序的并发性。在实际开发中,我们需要通过合适的同步机制来保证线程间的数据一致性。
希望这篇文章能帮助你更好地理解进程和线程,并掌握在 Linux 下的线程编程技巧。
相关文章:
线程与进程的深入解析及 Linux 线程编程
在操作系统中,进程和线程是进行并发执行的两种基本单位。理解它们的区别和各自的特点,能够帮助开发者更好地进行多任务编程,提高程序的并发性能。本文将探讨进程和线程的基础概念,及其在 Linux 系统中的实现方式,并介绍…...
在ubuntu上用Python的openpyxl模块操作Excel的案例
文章目录 安装模块读取Excel数据库取数匹配数据和更新Excel数据 在Ubuntu系统的环境下基本职能借助Python的openpyxl模块实现对Excel数据的操作。 安装模块 本次需要用到的模块需要提前安装(如果没有的话) pip3 install openpyxl pip3 install pymysql在操作前,需…...
【OS安装与使用】part6-ubuntu 22.04+CUDA 12.4运行MARL算法(多智能体强化学习)
文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 下载源码并安装2.2.2 安装缺失的依赖项2.2.3 训练执行MAPPO算法实例 三、疑问四、总结 一、待解决问题 1.1 问题描述 已配置好基础的运行环境,尝试运行MARL算法。 1…...
【Python爬虫(35)】解锁Python多进程爬虫:高效数据抓取秘籍
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
HarmonyOS 开发套件 介绍 ——上篇
HarmonyOS 开发套件 介绍 ——上篇 在当今科技飞速发展的时代,操作系统作为智能设备的核心,其重要性不言而喻。而HarmonyOS,作为华为推出的全新操作系统,正以其独特的魅力和强大的功能,吸引着越来越多的开发者和用户的…...
Linux 高级篇 日志管理、定制自己的Linux系统、备份与恢复
一、日志管理 (1)基本介绍 日志文件是重要的系统信息文件,记录了如用户登录、系统启动、系统安全、邮件及各种服务等相关重要系统事件在安全方面,日志也至关重要,它能记录系统日常发生的各类事情,可用于检…...
deepseek与其他大模型配合组合
DeepSeek与其他大模型的配合组合,展现了其在多个领域中的强大应用潜力和灵活性。以下是对DeepSeek与其他大模型配合组合的详细分析: 一、DeepSeek与华知大模型的组合 背景介绍: 华知大模型是同方知网与华为联手打造的,具备全学科…...
经验分享—WEB渗透测试中遇到加密内容的数据包该如何测试!
经验分享—WEB渗透测试中遇到加密内容的数据包该如何测试! 01 加解密的意义 现阶段的渗透测试让我发现越来越多的系统不只是在漏洞修补方面做了功夫,还对一些参数进行加密,干扰爬虫或者渗透测试的进行。 在我小白阶段看到下图这种加密方式…...
JUC并发—9.并发安全集合四
大纲 1.并发安全的数组列表CopyOnWriteArrayList 2.并发安全的链表队列ConcurrentLinkedQueue 3.并发编程中的阻塞队列概述 4.JUC的各种阻塞队列介绍 5.LinkedBlockingQueue的具体实现原理 6.基于两个队列实现的集群同步机制 4.JUC的各种阻塞队列介绍 (1)基于数组的阻塞…...
JSON格式,C语言自己实现,以及直接调用库函数(一)
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。 1. 简单对象 JSON 对象是由键值对组成,用花括号 {} 包裹&…...
MinkowskiEngine安装(CUDA11.8+torch2.0.1+RTX4070TI)
1、背景 1)因为项目要用这个库:MinkowskiEngine,Minkowski Engine — MinkowskiEngine 0.5.3 documentation 然后就用了之前安装好 MinkowskiEngine 的torch1.8.1,cuda11.1的环境。 2)自己的代码出现cuda不支持torch用gpu进行矩…...
Spring监听器Listener
目录 1、Spring监听器简介 2、事件(Event) 3、监听器(Listener) 3、事件发布器 4、监听器使用 4.1、自定义事件 4.2、自定义监听器 4.3、发布事件 4.4、测试 4.5、使用注解方式监听 4.6、异步事件处理 5、总结 1、Spri…...
【深度学习在图像配准中的应用与挑战】
图像配准在深度学习中的解决方案越来越多,尤其是通过卷积神经网络(CNN)和生成对抗网络(GAN)等方法,可以显著提升图像配准的效果,尤其是在处理复杂的非刚性变换和大范围的图像差异时。 1. 基于深…...
使用 Docker-compose 部署 MySQL
使用 Docker Compose 部署 MySQL 本文将详细指导如何使用 docker-compose 部署 MySQL,包括基本配置、启动步骤、数据持久化以及一些高级选项。通过容器化部署 MySQL,你可以快速搭建一个隔离的数据库环境,适用于开发、测试或小型生产场景。 关…...
blender笔记2
一、物体贴地 物体->变换->对齐物体 ->对齐弹窗(对齐模式:反方,相对于:场景原点,对齐:z)。 之后可以设置原点->原点--3d游标 二、面上有阴影 在编辑模式下操作过后,物体面有阴影。 数据-&g…...
特殊符号_符号图案_特殊符号大全
特殊符号↑返回顶部 © ℗ ร ಗ ย ☫ ౖ ஃ ⁜ ☊ ☋ ❡ ๑ ి ▧ ◘ ▩ ▣ ◙ ▨ ۞ ۩ ಔ ృ ☎ ☏ ⍝ ⍦ ▤ ▥ ▦ ✠ @ ಓ ↂ ూ ☮ ி ﺴ ✈ ✉ ✁ ✎ ✐ 〄 # ‡ ☪ ⌚ ☢ ▪ ▫ ✆ ✑ ✒ ☌ ❢ ▬ ☍ □ ■ ؟ ‼ ‽ ☭ ✏ ⌨…...
Unity学习part4
1、ui界面的基础使用 ui可以在2d和矩形工具界面下操作,更方便,画布与游戏窗口的比例一般默认相同 如图所示,图片在画布上显示的位置和在游戏窗口上显示的位置是相同的 渲染模式:屏幕空间--覆盖,指画布覆盖在游戏物体渲…...
【AI绘画】大卫• 霍克尼风格——自然的魔法(一丹一世界)
大卫• 霍克尼,很喜欢这个老头,“艺术是一场战斗”。老先生零九年有了iphone,开始用iphone画画,一零年开始用ipad画画,用指头划拉,据说五分钟就能画一幅,每天早上随手画几幅送给身边的朋友。很c…...
MySQL日志undo log、redo log和binlog详解
MySQL 日志:undo log、redo log、binlog 有什么用? 一、前言 在MySQL数据库中,undo log、redo log和binlog这三种日志扮演着至关重要的角色,它们各自承担着不同的功能,共同保障了数据库的正常运行和数据的完整性。了解…...
C++中的指针
一.指针的定义 在C中,指针是一种特殊的变量,它存储另一个变量的内存地址。简单的说,指针是指向另一个数据类型的“指针”或“引用”,我们可以通过指针来间接操作其他变量的值。 指针的基本语法: 数据类型 *指针变量名 …...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础
在构建任何动态、数据驱动的Web API时,一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说,深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言,以及学会如何在Python中操作数据库,是…...
