Linux C/C++编程中的多线程编程基本概念

news2024/12/30 2:06:21
【图书推荐】《Linux C与C++一线开发实践(第2版)》_linux c与c++一线开发实践pdf-CSDN博客
《Linux C与C++一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com)

8.2.1  操作系统和多线程

要在应用程序中实现多线程,必须有操作系统的支持。Linux 32位或64位操作系统对应用程序提供了多线程的支持,所以Windows NT/2000/XP/7/8/10是多线程操作系统。根据进程与线程的支持情况,可以把操作系统大致分为如下几类:

(1)单进程、单线程,MS-DOS大致是这种操作系统。

(2)多进程、单线程,多数UNIX(及类UNIX的Linux)是这种操作系统。

(3)多进程、多线程,Win32(Windows NT/2000/XP/7/8/10等)、Solaris 2.x和OS/2都是这种操作系统。

(4)单进程、多线程,VxWorks是这种操作系统。

具体到Linux C++的开发环境,它提供了一套POSIX API函数来管理线程,用户既可以直接使用这些POSIX API函数,也可以使用C++自带的线程类。作为一名Linux C++开发者,这两者都应该会使用,因为在Linux C++程序中,这两种方式都有可能出现。

8.2.2  线程的基本概念

现代操作系统大多支持多线程概念,每个进程中至少有一个线程,所以即使没有使用多线程编程技术,进程也含有一个主线程,所以也可以说,CPU中执行的是线程,线程是程序的最小执行单位,是操作系统分配CPU时间的最小实体。一个进程的执行说到底是从主线程开始的,如果需要,可以在程序任何地方开辟新的线程,其他线程都是由主线程创建的。一个进程正在运行,也可以说是一个进程中的某个线程正在运行。一个进程的所有线程共享该进程的公共资源,比如虚拟地址空间、全局变量等。每个线程也可以拥有自己私有的资源,如堆栈、在堆栈中定义的静态变量和动态变量、CPU寄存器的状态等。

线程总是在某个进程环境中创建的,并且会在这个进程内部销毁。线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时,该进程所产生的线程都会被强制退出并清除。线程可与属于同一进程的其他线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和线程栈,线程栈用于维护线程在执行代码时需要的所有函数参数和局部变量)。

相对于进程来说,线程所占用的资源更少。比如创建进程,系统要为它分配很大的私有空间,占用的资源较多;而对于多线程程序来说,由于多个线程共享一个进程地址空间,因此占用的资源较少。此外,进程间切换时,需要交换整个地址空间,而线程间切换时,只是切换线程的上下文环境,因此效率更高。在操作系统中引入线程带来的主要好处是:

(1)在进程内创建、终止线程比创建、终止进程要快。

(2)同一进程内线程间的切换比进程间的切换要快,尤其是用户级线程间的切换。

(3)每个进程具有独立的地址空间,而该进程内的所有线程共享该地址空间,因此线程的出现可以解决父子进程模型中子进程必须复制父进程地址空间的问题。

(4)线程对解决客户/服务器模型非常有效。

虽然多线程给应用开发带来了不少好处,但并不是所有情况下都要去使用多线程,要具体问题具体分析。通常在下列情况下可以考虑使用多线程:

(1)应用程序中的各任务相对独立。

(2)某些任务耗时较多。

(3)各任务有不同的优先级。

(4)一些实时系统应用。

值得注意的是,一个进程中的所有线程共享它们父进程的变量,但同时每个线程可以拥有自己的变量。

8.2.3  线程的状态

一个线程在从创建到结束这一生命周期中,总是处于下面4个状态中的一个。

1)就绪态

线程能够运行的条件已经满足,只是在等待处理器(处理器要根据调度策略来把就绪态的线程调度到处理器中运行)。处于就绪态的原因可能是线程刚刚被创建(刚创建的线程不一定马上运行,一般先处于就绪态),也可能是刚刚从阻塞状态中恢复,还可能是因被其他线程抢占而处于就绪态。

2)运行态

运行态表示线程正在处理器中运行,正占用着处理器。

3)阻塞态

由于在等待处理器之外的其他条件而无法运行的状态叫作阻塞态。这里的其他条件包括I/O操作、互斥锁的释放、条件变量的改变等。

4)终止态

终止态就是线程的线程函数运行结束或被其他线程取消后处于的状态。处于终止态的线程虽然已经结束了,但它所占资源还没有被回收,而且还可以被重新复活。我们不应该长时间让线程处于这种状态,线程处于终止态后应该及时进行资源回收,下面会讲到如何回收。

8.2.4  线程函数

线程函数就是线程创建后进入运行态后要执行的函数。执行线程说到底就是执行线程函数。这个函数是我们自定义的,然后在创建线程时把我们的函数作为参数传入线程创建函数。

同理,中断线程的执行就是中断线程函数的执行,以后再恢复线程的时候,就会在前面线程函数暂停的地方继续执行下面的代码。结束线程也就不再运行线程函数。线程的函数可以是一个全局函数或类的静态函数,比如在POSIX线程库中,它通常这样声明:

void *ThreadProc (void *arg)

其中,参数arg指向要传给线程的数据,这个参数是在创建线程的时候作为参数传入线程创建函数中的。函数的返回值应该表示线程函数运行的结果:成功还是失败。注意函数名ThreadProc可以是自定义的函数名,这个函数是用户自己先定义好,然后由系统来调用。

8.2.5  线程标识

既然句柄是用来标识线程对象的,那线程本身用什么来标识呢?在创建线程的时候,系统会为线程分配唯一的ID作为线程的标识,这个ID从线程创建开始就存在,一直伴随着线程的结束才消失。线程结束后,该ID就自动不存在,我们不需要去显式清除它。

通常线程创建成功后会返回一个线程ID。

8.2.6  C++多线程开发的两种方式

在Linux C++开发环境中,通常有两种方式来开发多线程程序:一种是利用POSIX多线程API函数来开发多线程程序,另一种是利用C++自带线程类来开发多线程程序。这两种方式各有利弊。前一种方法比较传统,后一种方法比较新,是C++11推出的方法。为何C++程序员也要熟悉POSIX多线程开发呢?这是因为C++11以前,在C++里面使用多线程一般都是利用POSIX多线程API,或者把POSIX多线程API封装成类,再在公司内部供大家使用。因此,一些老项目都是和POSIX多线程库相关的,这也使得我们必须熟悉它,因为很可能进入公司后会要求维护以前的程序代码。而C++自带线程类很可能在以后开发新的项目时会用到。总之,技多不压身。

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

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

相关文章

FPGA工作原理、架构及底层资源

FPGA工作原理、架构及底层资源 文章目录 FPGA工作原理、架构及底层资源前言一、FPGA工作原理二、FPGA架构及底层资源 1.FPGA架构2.FPGA底层资源 2.1可编程输入/输出单元简称(IOB)2.2可配置逻辑块2.3丰富的布线资源2.4数字时钟管理模块(DCM)2.5嵌入式块 …

C语言程序设计P5-3【应用函数进行程序设计 | 第三节】——知识要点:函数的嵌套调用和递归调用

知识要点:函数的嵌套调用和递归调用 视频 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 本任务要求用递归法求 n!。 我们知道n!n(n-1)(n-2)……1n(n-1)!递归公式为: 1.上面公式分解为n!n(n-1)!,即将求n!的问题变为…

word实践:正文/标题/表图等的共用模板样式设置

说在前面 最近使用word新建文件很多,发现要给大毛病,每次新建一个word文件,标题/正文的字体、大小和间距都要重新设置一遍,而且每次设置这些样式都忘记了参数,今天记录一下,以便后续方便查看使用。现在就以…

【工具变量】上市公司企业劳动密集度数据(2008-2023年)

一、测算方式: 参考《数量经济技术经济研究》陈勇兵(2023)老师的做法,使用员工数量与销售收入的比值作为劳动密集度的度量标准* o/ b% C( e* U我们做的比他完善,分为四类大家可以做核心变量或者稳健性检验Labor1&…

YOLOv11修改推理图片的标签字体大小

先打开ultralytics/utils/plotting.py,并搜索font scale(vscode快捷键ctrlF): 在这行代码动手脚,例如调小分母就是把字改大: self.sf self.lw 完成,可以正常运行:

TCP Analysis Flags 之 TCP Spurious Retransmission

前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…

在paddle中安装python-bidi出错

翻看网上解决方式,是由于系统中缺少 Rust 及其包管理器 Cargo。python-bidi 依赖 Rust 来编译其扩展,如果没有安装 Rust 和 Cargo,安装过程将无法继续。 解决方式 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh但是我的终端…

自动化测试工具Ranorex Studio(五十四)-CSV文件

CSV文件 你也可以通过选择CSV文件数据连接器来使用CSV文件为你的测试套件提供数据。在添加了CSV数据连接器后,管理数据源的对话框将被打开。 你可以在表色标示部分编辑数据连接器的名字,也可以在绿色标示的部分选择你要用的CSV文件。选择或者取消蓝色标示…

Flume基础概念

目录 作用组件构成ClientFlowAgentSourceSinkEvent 和Log4j的区别与定位事务传出流程输入到sourcesource端输入Channel 接收输入到SinkSink输出 作用 Flume可以从各种来源(如日志文件、消息队列、网络数据、文件系统、数据库等)收集数据,并将…

FPGA实战篇(IP核之MMCM/PLL实验)

1.MMCM/PLL IP 核简介 锁相环作为一种反馈控制电路,其特点是利用外部输入的参考信号控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪,所以锁相环通常用于闭环跟踪电路。 锁相环在工作的过程中,当…

Numpy基础练习

import numpy as np 1.创建一个长度为10的一维全为0的ndarray对象,然后让第5个元素等于1 n np.zeros(10,dtypenp.int32) n[4] 12.创建一个元素从10到49的ndarray对象 n np.arrange(10,50)3.将第2题的所有元素位置反转 n[::-1]使用np.random.random创建一个10*10的ndarray对象…

Probabilistic Face Embeddings 论文阅读

Probabilistic Face Embeddings 论文阅读 Abstract1. Introduction2. Related Work3. Limitations of Deterministic Embeddings4. Probabilistic Face Embeddings4.1. Matching with PFEs4.2. Fusion with PFEs4.3. Learning 5. Experiments5.1. Experiments on Different Bas…

基于SSM框架企业人事管理系统的设计与实现

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 IDE环境: Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境: Tomcat 7.x,8.x,9.x版本均可 操作系统…

云数据库 MongoDB

MongoDB 是一个基于文档的 NoSQL 数据库,它与传统的关系型数据库不同,采用的是灵活的文档结构(类似 JSON 格式)。MongoDB 是开源的,且高度可扩展,通常用于处理大量的非结构化或半结构化数据。 云数据库 Mon…

AcWing 3496. 特殊年份

文章目录 前言代码思路 前言 写简单题没啥。反正都是要写的&#xff0c;先把能拿到的分数拿了&#xff0c;之后有机会再去啃一啃硬骨头。啃不下来就算了。 代码 #include<bits/stdc.h> using namespace std; char a1[10],a2[10],a3[10],a4[10],a5[10]; int main(){cin…

Vite+Vue3项目实战:组件化开发与通信指南

一、典型的ViteVue3项目结构 续上文成功创建Vue3项目的脚手架&#xff0c;通过visual Studio Code软件打开刚刚创建的文件夹&#xff0c;将会看到这样一个项目结构。 使用Vite构建Vue3项目时&#xff0c;项目结构通常遵循一定的组织规则&#xff0c;以保持代码的清晰和可维护性…

Html笔记()蜘蛛纸牌之卡牌吸附

目的 蜘蛛纸牌中要实现牌组的连接&#xff0c;就需要吸附功能。从效果图中可以看出我们把一张牌拖到另一张卡牌上的时候&#xff0c;它会自动吸附过去并且左对齐。 效果 代码 <!DOCTYPE html> <html><head><style>body {display: flex;justify-cont…

CDC YAML 在阿里云的最佳实践

摘要&#xff1a;本文投稿自阿里云开源大数据平台数据通道团队&#xff0c;主要介绍了 Flink CDC YAML 在实时计算Flink版的最佳实践。内容分为以下五个部分&#xff1a; CDC YAML 简介CDC YAML 核心能力CDC YAML 应用场景阿里云 Flink CDC 企业级功能十分钟在阿里云免费实现一…

在21世纪的我用C语言探寻世界本质——字符函数和字符串函数(2)

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、strncpy函数的使用二、strncat函数的使用三、strncmp函数的使用四、strstr的使用和模拟实现五、strtok函数的使用六、strerror和pe…

Cursor vs VSCode:主要区别与优势分析

Cursor - The AI Code Editor 1. AI 集成能力 Cursor的优势 原生AI集成&#xff1a; # Cursor可以直接通过快捷键调用AI # 例如&#xff1a;按下 Ctrl K 可以直接获取代码建议 def complex_function():# 在这里&#xff0c;你可以直接询问AI如何实现功能# AI会直接在编辑器中…