嵌入式Linux-线程的开始

news2024/10/7 4:30:18

1. 线程的开始

1.1 线程的含义

学习了进程相关的知识内容,对进程有了一个比较全面的认识和理解,从今开始呢,我们要学习一个新的概念,叫做线程!
那什么是线程呢?

与进程类似,线程是允许应用程序并发执行多个任务的一种机制,线程是参与系统调度的最小单位。它被包含在进程之中,是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流(或者说是执行路线、执行流),一个进程中可以创建多个线程,多个线程实现
并发运行,每个线程执行不同的任务。譬如某应用程序设计了两个需要并发运行的任务 task1 和 task2,可将两个不同的任务分别放置在两个线程中,虽然线程的概念比较简单,但是其所涉及到的内容比较多,所以我会和进程一样,分出很多个小的知识点,慢慢总结!

1.2 线程是如何创建起来的?

当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread),因为它是程序一开始时就运行的线程。应用程序都是以 main()做为入口开始运行的,所以 main()函数就是主线程的入口函数,main()函数所执行的任务就是主线程需要执行的任务。

所以由此可知,任何一个进程都包含一个主线程,只有主线程的进程称为单线程进程,譬如前面章节内容中所编写的所有应用程序都是单线程程序,它们只有主线程;既然有单线程进程,那自然就存在多线程进程,所谓多线程指的是除了主线程以外,还包含其它的线程,其它线程通常由主线程来创建(调用pthread_create 创建一个新的线程),那么创建的新线程就是主线程的子线程。

主线程的重要性体现在两方面:

  1. 其它新的线程(也就是子线程)是由主线程创建的;
  2. 主线程通常会在最后结束运行,执行各种清理工作,譬如回收各个子线程。

1.3 线程的特点

同一进程中的多个线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack,我们称为线程栈),自己的寄存器环境(register context)、自己的线程本地存储(thread-local storage)。(这恰恰是我们后续学习需要重点关注和学习的)

在多线程应用程序中,通常一个进程中包括了多个线程,每个线程都可以参与系统调度、被 CPU 执行,线程具有以下一些特点:

  1. 线程不单独存在、而是包含在进程中;
  2. 线程是参与系统调度的基本单位;
  3. 可并发执行。同一进程的多个线程之间可并发执行,在宏观上实现同时运行的效果;
  4. 共享进程资源。同一进程中的各个线程,可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量等等。

1.4 进程与线程的比较

进程创建多个子进程可以实现并发处理多任务(本质上便是多个单线程进程),多线程同样也可以实现(一个多线程进程)并发处理多任务的需求,那我们究竟选择哪种处理方式呢?首先我们就需要来分析下多进程和多线程两种编程模型的优势和劣势。
多进程编程的劣势:

  1. 进程间切换开销大。多个进程同时运行(指宏观上同时运行,无特别说明,均指宏观上),微观上依然是轮流切换运行,进程间切换开销远大于同一进程的多个线程间切换的开销,通常对于一些中小型应用程序来说不划算。
  2. 进程间通信较为麻烦。每个进程都在各自的地址空间中、相互独立、隔离,处在于不同的地址空间中,因此相互通信较为麻烦,需要管道,信号等。
    多线程能够弥补上面的问题:
  3. 同一进程的多个线程间切换开销比较小。
  4. 同一进程的多个线程间通信容易。它们共享了进程的地址空间,所以它们都是在同一个地址空间中,通信容易。
  5. 线程创建的速度远大于进程创建的速度。
  6. 多线程在多核处理器上更有优势!
    我怎么感觉有点像在黑进程的意思,不过,总而言之,多线程无论是处理各个程序的信息,都是一个相当很好的选择,开销小,灵活多变。

2. 并发和并行

2.1 概念

在前面的内容中,曾多次提到了并发这个概念,与此相类似的概念还有并行、串行,这里和大家聊一聊这些概念含义的区别吧。

对于串行比较容易理解,它指的是一种顺序执行,譬如先完成 task1,接着做 task2、直到完成 task2,然后做 task3、直到完成 task3……依次按照顺序完成每一件事情,必须要完成上一件事才能去做下一件事,只有一个执行单元,这就是串行运行。
在这里插入图片描述
并行与串行则截然不同,并行指的是可以并排/并列执行多个任务,这样的系统,它通常有多个执行单元,所以可以实现并行运行,譬如并行运行 task1、task2、task3。
在这里插入图片描述
并行运行并不一定要同时开始运行、同时结束运行,只需满足在某一个时间段上存在多个任务被多个执行单元同时在运行着,譬如:
在这里插入图片描述
相比于串行和并行,并发强调的是一种时分复用,与串行的区别在于,它不必等待上一个任务完成之后在做下一个任务,可以打断当前执行的任务切换执行下一个任何,这就是时分复用。在同一个执行单元上,将时间分解成不同的片段(时间片),每个任务执行一段时间,时间一到则切换执行下一个任务,依次这样轮训(交叉/交替执行),这就是并发运行。如下图所示:
在这里插入图片描述
举几个简单的小案例,方便理解一下吧:

  1. 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接电话,这就说明你不支持并发也不支持并行,仅仅只是串行。
  2. 你吃饭吃到一半,电话来了,你停下吃饭去接了电话,电话接完后继续吃饭,这说明你支持并发。
  3. 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。

需要注意的是,并行运行情况下的多个执行单元,每一个执行单元同样也可以以并发方式运行。从通用角度上介绍完这三个概念之后,类到计算机系统中,首先我们需要知道两个前提条件:

  1. 多核处理器和单核处理器:对于单核处理器来说,只有一个执行单元,同时只能执行一条指令;而对于多核处理起来说,有多个执行单元,可以并行执行多条指令,譬如8核处理器,那么可以并行执行8条不同的指令。
  2. 计算机操作系统中,通常同时运行着几十上百个不同的线程,在单核或多核处理系统中都是如此!

tips:像普通的Linux单片机,像全志的,正点原子的,基本都是单核的soc,所以都是我们常说的单核处理器,只能采用并发运行系统中的线程,而肯定不可能是串行,而事实上确实如此。内核实现了调度算法,用于控制系统中所有线程的调度,简单点来说,系统中所有参与调度的线程会加入到系统的调度队列中,它们由内核控制,每一个线程执行一段时间后,由系统调度切换执行调度队列中下一个线程,依次进行。

2.2 什么是同时运行

计算机处理器运行速度是非常快的,在单个处理核心虽然以并发方式运行着系统中的线程(微观上交替/交叉方式运行不同的线程),但在宏观上所表现出来的效果是同时运行着系统中的所有线程,因为处理器的运算速度太快了,交替轮训一次所花费的时间在宏观上几乎是可以忽略不计的,所以表示出来的效果就是同时运行着所有线程。
这就好比现实生活中所看到的一些事情,它所给带来的视角效果,譬如一辆车在高速上行驶,有时你会感觉到车的轮毂没有转动,一种视角暂留现象,因为车轮转动速度太快了,人眼是看不清的,会感觉车轮好像是静止的,事实上,车轮肯定是在转动着。

本章主要帮助大家充分理解线程与进程的一个不同,帮助大家构建进程与线程的包容关系,建立起一个框架,在后面的学习中,我们通过编程来感受线程的神奇!

本文参考正点原子的嵌入式LinuxC应用编程。

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

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

相关文章

java中的方法2023016

定义方法(VS函数): 方法是类或对象的行为特征的抽象,方法是类或对象最重要的组成部分。但从功能上来看,方法完全类似于传统结构化程序设计里的函数。区别是:Java里的方法不能独立存在,所有的方法…

《精力管理》阅读笔记

目录 什么是精力及如何管理精力 高效表现有节奏——劳逸结合的平衡 管理精力的三个步骤 明确目标——知道什么最重要才能全情投入 正视现实——你的精力管理做得如何 付诸行动——积极仪式习惯的力量 精力管理的四个基本原则 体能精力——为身体添柴加火 情感精力——把…

微信小程序----全局数据共享

1.什么是全局数据共享 全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。 2.小程序中的全局数据共享方案 在小程序中,可使用 mobx-miniprogram 配合 mobx-miniprog…

【SAP Abap】X档案:SAP Native SQL 简介及本地数据库访问实现方式(EXEC SQL、ADBC、AMDP)

SAP Native SQL 简介及本地数据库访问实现方式(EXEC SQL、ADBC、AMDP)1、SAP Open SQL 与 Native SQL 的特点2、实现方式方式一:Native SQL(Exec SQL)(1)获取单值(2)获取…

iOS上架appstore详细教材

假如你用原生xcode开发,上架是相对简单。 但假如是用hbuilderx这些uniapp框架开发,没有mac电脑,没有xcode,那么还能上架吗?是可以的,你看完这篇文章,就知道如何在没有mac电脑的情况下&#xff…

【小知识】目标检测各类指标概念总结

文章目录前言一、AP(Average Precision)1.1 TP(True Positive)、FP(False Positive)、FN(False Negative)1.2 Precision(查准率)、Recall(召回率/…

【LeetCode】Day201-重新安排行程

题目 332.重新安排行程【困难】 题解 这道题的几个难点: 一个行程中,如果航班处理不好容易变成一个圈,成为死循环有多种解法,字母序靠前排在前面,应该如何记录映射关系?使用回溯法,终止条件…

贪心 376. 摆动序列

376. 摆动序列 难度中等827 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, [1, 7, 4, 9,…

opencv的图像基本操作_3

模板匹配 模板匹配和卷积很像,模板在原图像上滑动,并在滑过的区域上计算匹配数值,通过匹配数值衡量模板匹配程度,opencv中有6种计算方法,从原点开始计算,将每次计算的结果放到一个矩阵,最后输出…

CSS 加载进度条

CSS 加载进度条 环形加载条 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>环形加载条</title><style type"text/css">.box {width: 200px;height: 200px;border: 1px solid silver;display: flex…

永磁同步电机全速域控制指南

一直都想知道永磁同步电机的转速从零增加到极限这个过程会发生什么&#xff0c;这篇文章介绍一下永磁同步电机全速域矢量控制的全过程&#xff0c;即电机的转速从零开始逐渐增加&#xff0c;如何设计电流环电流使得电机输出恒定转矩&#xff0c;且保持转速稳定。能把这个过程想…

ruoyi-vue版本(七)定时任务 相关的源码解析,也就是ruoyi-quartz 模块的解析

目录1 需求2 解析2.1 工具类里面的关系2.2 新增定时任务2.3 回显定时任务2.4 修改定时任务3 总结1 需求 我们打开若依项目&#xff0c;看到页面上有一个定时任务模块 我们接下来就是解析若依项目和定时任务相关的所有的文件&#xff0c;以及他是如何实现定时的&#xff0c;背…

Kubernetes 资源监控

Kubernetes 资源监控一、前言二、使用三、实现原理3.1 数据链路3.2 kube-aggregator3.3 监控体系 ❤️3.4 kubelet3.5 cadvisor3.6 cgroup四、问题4.2 kubectl top pod 内存怎么计算&#xff0c;包含 pause容器吗4.3 kubectl top node 怎么计算&#xff0c;和节点上直接 top 有…

C语言深度剖析 -- 32个关键字(上)

文章目录C语言关键字我们人生中第一个C语言程序变量的定义与声明变量的作用域与生命周期最宽宏大量的关键字 -- auto最快的关键字 -- register&#xff08;寄存器变量&#xff09;最名不符实的关键字 -- static基本内置数据类型 -- char、short、int、long、float、double最冤枉…

transformers学习笔记2

pipeline快速使用from transformers import pipelineclassifier pipeline("sentiment-analysis") classifier(["Ive been waiting for a HuggingFace course my whole life.","I hate this so much!",] )[{label: POSITIVE, score: 0.959804713…

概述.runoob.html

<!DOCTYPE html> 声明为 HTML5 文档<html> 元素是 HTML 页面的根元素<head> 元素包含了文档的元&#xff08;meta&#xff09;数据&#xff0c;如 <meta charset"utf-8"> 定义网页编码格式为 utf-8。<title> 元素描述了文档的标题<…

【Linux线程安全】

Linux线程安全Linux线程互斥进程线程间的互斥相关背景概念互斥量mutex互斥量的接口互斥量实现原理探究可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见的不可重入的情况常见的可重入的情况可重入与线程安全联系可重入与线程安全区别常见锁概念死锁死锁的四…

套接字编程基础

文章目录IPV4套接字地址结构IPv6套接字地址结构字节排序函数地址转换函数IPV4套接字地址结构 IPv4套接字定义在<netinet/in.h> 投文件中&#xff0c;定义如下&#xff1a; struct in_addr {in_addr_t s_addr; } struct sockaddr_in {uint8_t sin_len; // 长度字段sa_fa…

【青训营】性能优化和自动内存管理

本文整理自&#xff1a;第五届字节跳动青年训练营 后端组 什么是性能优化 提高软件系统处理能力&#xff0c;减少不必要消耗&#xff0c;充分利用计算机算力 业务层优化 针对特定场景和具体问题容易获得较大收益 语言运行时优化 面向全公司的优化&#xff0c;非特定场景解决更…

力扣55.跳跃游戏(比较简单)

文章目录力扣55.跳跃游戏&#xff08;比较简单&#xff09;题目描述算法思路代码实现力扣55.跳跃游戏&#xff08;比较简单&#xff09; 题目描述 给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度…