【操作系统】进程与线程概念基础知识

news2024/10/6 2:21:36

进程与线程概念基础知识

  • 进程
    • 进程的概念
    • 进程控制块
    • 进程状态
    • 进程三状态模型
    • 挂起进程模模型
    • 进程的上下文切换
    • 进程控制
  • 线程
    • 为什么引入线程
    • 线程的概念
    • 线程与进程的比较
    • 线程的上下文切换
    • 线程的实现

进程

进程的概念

1. 进程的定义: 进程是指一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程

2. 进程的组成: 进程包含了正在运行的一个程序的所有状态信息(代码、数据、状态寄存器、通用寄存器、进程占用系统资源)

3. 进程的特点:

  • 动态性: 可动态地创建,结果进程;
  • 并发性: 进程可以被独立调度并占用处理机运行;
  • 独立性: 不同进程的工作不相互影响;
  • 制约性: 因访问共享数据 / 资源或进程间同步而产生制约。

4. 进程和程序的联系:

  • 进程是操作系统处于执行状态程序的抽象(动态的)
    • 程序 = 文件(静态的可执行文件)
    • 进程 = 执行中的程序 = 程序 + 执行状态
  • 同一个程序的多次执行过程对应为不同进程,如ls多次执行对应不同进程
  • 进程执行需要的资源 :内存(保存代码和数据)+ CPU(执行指令)

5. 进程和程序的区别:

  • 进程是动态的,程序是静态的
  • 进程是暂时的,程序是永久的
  • 进程与程序的组成不同

进程控制块

描述进程的数据结构:进程控制块 (Process Control Block)
操作系统为每个进程都维护了一个PCB,用来保存与该进程有关的各种状态信息。

1. 进程控制块: 操作系统管理控制进程运行所用的信息集合。

  • 操作系统用PCB来描述进程的基本情况以及运行变化的过程
  • PCB是进程存在的唯一标志。

2. 使用进程控制块

  • 进程的创建:为该进程生成一个PCB
  • 进程的终止: 回收它的PCB
  • 进程的组织管理: 通过对PCB的组织管理来实现

PCB具体包含什么信息? 如何组织的? 进程的状态转换?

3. 进程控制块内容: 进程标识信息、处理机现场保存(多进程交替运行时用)、进程控制信息

PCB含有以下三大类信息:

进程标志信息。如本进程的标志符,本进程的产生者标志(父进程标志);用户标志

处理机状态信息保存区。保存进程的运行现场信息:

  • 用户可见寄存器; 用户程序可以使用的数据,地址等寄存器。

  • 控制和状态寄存器; 如程序计数器(PC),程序状态字(PSW)。

  • 栈指针;过程调用,系统调用,中断处理和返回时需要用到它。

进程控制信息

  • 调度和状态信息:进程和处理机制使用情况调度

  • 进程间通信信息:为支持进程间与通信相关的各种标志,信号,信件等

  • 存储管理信息:包含有指向本进程映像存储空间的数据结构。

  • 进程所用资源:说明由进程打开,进程使用的系统资源。 如打开的文件等。

  • 有关数据结构的链接信息:进程可以连接到一个进程队列中,或连接到相关的其他进程的PCB。

4. 进程控制块的组织:

  • 链表: 同一状态的进程其PCB成一链表,多个状态对应多个不同的链表。各状态的进程形成不同的链表:就绪链表,阻塞链表

  • 索引表: 同一状态的进程归入一个index表(由index指向PCB),多个状态对应多个不同的index表。各状态的进行形成不同的索引表:就绪索引表,阻塞索引表

进程状态

进程的生命周期划分: 创建、执行、等待、抢占、唤醒、结束

进程创建
引起进程创建的三种情况:

  • 系统初始化时
  • 用户请求 创建一个新进程
  • 正在运行的程序执行了创建进程的系统调用

进程执行
内核选择一个就绪的进程,让它占用处理机并执行(后续的调度算法)

进程等待
进程进入等待(阻塞)的情况

  • 请求并等待系统服务,无法马上完成
  • 启动某种操作,无法马上完成
  • 需要的数据没有到达

进程只能自己阻塞自己,因为只有进程自身才能知道何时需要等待某种事件的发生。

进程抢占
进程会被抢占的情况

  • 高优先级进程就绪
  • 进程执行当前时间完

进程唤醒
唤醒进程的情况:

  • 被阻塞进程需要的资源可被满足
  • 被阻塞进程等待的事件到达

进程只能被别的进程或操作系统唤醒

进程结束
进程结束的情况

  • 正常退出(自愿的)
  • 错误退出(自愿的)
  • 致命错误(强制性的)
  • 被其他进程所杀(强制性的)

sleep()系统调用对应的进程状态变化

进程切换

进程三状态模型

三状态模型:就绪、运行、等待

进程的三种基本状态:
运行状态(Running): 当一个进程正在处理机上运行时
就绪状态(Ready): 一个进程获得了除处理机之外的一切所需资源,一旦得到处理机即可运行
等待/阻塞状态(Blocked): 一个进程正在等待某一时间而暂停运行时。 如等待某资源,等待输入 / 输出完成。

进程其它的基本状态:
创建状态(New):一个进程正在被创建,还没被转到就绪状态之前的状态。
结束状态(Exit): 一个进程正在从系统中消失时的状态,这是因为进程结束或由于其它原因所导致。

可能的状态变化如下:

  • NULL → New:一个新进程被产生出来执行一个程序。

  • New → Ready: 当进程创建完成并初始化后,一切就绪准备运行时,变为就绪状态。是否会持续很久?很快。

  • Ready → Running :处于就绪态的进程被进程调度程序选中后,就分配到处理机上来运行。(怎么选中取决于后面的调度算法)

  • Running → Exit :当进程表示它已经完成或者因出错,当前运行进程会由操作系统作结束处理。

  • Running → Ready :处于运行状态的进程在其运行过程中,由于分配它的处理机时间片用完而让出处理机。谁完成?OS。

  • Running → Blocked: 当进程请求某样东西且必须等待时。例如?等待一个计时器的到达、读 / 写文件 比较慢等。

  • Blocked → Ready :当进程要等待某事件到来时,它从阻塞状态变到就绪状态。例如?事件到达等。谁完成?OS。

挂起进程模模型

Why?为了合理且充分地利用系统资源。

进程在挂起状态时,意味着进程没有占用内存空间,处在挂起状态的进程映像在磁盘上,目的是减少进程占用内存

1. 挂起状态
阻塞挂起状态(Blocked-suspend): 进程在外存并等待某事件的出现。
就绪挂起状态(Ready-suspend): 进程在外存,但只要进入内存,即可运行。

与挂起相关的状态转换

  • 阻塞到阻塞挂起:有进程处于就绪状态或就绪进程要求更多内存资源时,会进行这种转换,以提交新进程或运行时就绪进程。

  • 就绪到就绪挂起: 当有高优先级阻塞进程和低优先级就绪进程时,系统会选择挂起低优先级就绪进程。

  • 运行到就绪挂起: 对抢先式分时系统,当有高优先级阻塞挂起进程因事件出现而进入就绪挂起时,系统可能会把运行进程转导就绪挂起状态。

2. 解挂 / 激活状态
把一个进程从外存转到内存,可能有以下几种情况:

  • 就绪挂起到就绪: 没有就绪进程或挂起就绪进程优先级高于就绪进程时,会进行这种转换。

  • 阻塞挂起到阻塞: 当一个进程释放足够内存时,系统会把一个高优先级阻塞挂起进程转换为阻塞进程。

3. 状态队列

  • 由操作系统来维护一组队列,表示系统中所有进程的当前状态
  • 不同队列表示不同状态,就绪队列、各种等待队列
  • 根据进程状态不同,进程PCB加入相应队列,进程状态变化时,它所在的PCB会从一个队列换到另一个

进程的上下文切换

  各个进程之间是共享 CPU 资源的,在不同的时候进程之间需要切换,让不同的进程可以在 CPU 执行,那么这个一个进程切换到另一个进程运行,称为进程的上下文切换

  • 暂停当前运行的进程,从而运行状态变成其他状态
  • 调度另一个进程从就绪状态变成运行状态

进程切换的要求

  • 切换前,保存进程上下文
  • 切换后,恢复进程上下文
  • 快速切换

进程生命周期的信息

  • 寄存器(PC,SP,…)
  • CPU状态
  • 内存地址空间

进程是由内核管理和调度的,所以进程的切换只能发生在内核态。

所以,进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。

  通常,会把交换的信息保存在进程的 PCB,当要运行另外一个进程的时候,我们需要从这个进程的 PCB取出上下文,然后恢复到 CPU 中,这使得这个进程可以继续执行,如下图所示:

上下文切换图示:

发生进程上下文切换有哪些场景?

  • 为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。(时间片流转
  • 进程在系统资源不足够(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程行;(内存不足被挂起
  • 当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度;(sleep延时函数
  • 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行;(被更高优先级任务抢占
  • 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序;(硬件中断

进程控制

  熟知了进程的状态变迁和进程的数据结构 PCB 后,再来看看进程的创建、终止、阻塞、唤醒的过程,这些过程也就是进程的控制

01 创建进程

  操作系统允许一个进程创建另一个进程,而且允许子进程继承父进程所拥有的资源,当子进程被终止时,其在父进程处继承的资源应当还给父进程。同时,终止父亲进程时同时也会终止其所有的子进程。

1. 创建进程的过程如下:

  • 为新进程分配一个唯⼀的进程标识号,并申请⼀个空白的 PCB,若申请失败则创建失败;
  • 为进程分配资源,此处如果资源不足,进程就会进入等待状态,以等待资源;
  • 初始化 PCB;
  • 如果进程的调度队列能够接纳新进程,那就将进程插⼊到就绪队列,等待被调度运行;

2. 创建进程相关函数介绍

Unix进程创建系统调用:fork / exec

  • fork()把一个进程复制成二个进程(parent old PlD, child new PlD)
  • exec()用新程序来重写当前进程,PID没有改变

用fork()和exec()创建进程示例:

int pid = fork();	//创建子进程
if(pid == 0)		//子进程
{
	//Do anything
	//加载其他任何一个程序
	exec("program", argc, argv[0], argv[1], ...); 
}
  • fork() 创建一个继承的子进程

    • 复制父进程的所有变量和内存
    • 复制父进程的所有CPU寄存器(有一个寄存器除外)
  • fork() 的返回值

    • 子进程的fork()返回 0
    • 父进程的fork()返回子进程标识符
    • fork()返回值可方便后续使用,子进程可使用getpid()获取PID

3. fork()的地址空间复制
  fork()执行过程对于子进程而言,是在调用时间对父进程地址空间的一次复制,对于父进程fork()返回child PlD, 对于子进程返回值为0

  
02 进程加载

执行exec()时,进程可能处于不同的状态。

4. 程序加载和执行
系统调用exec()加载程序取代当前运行的进程。

In the parent process:
main()
...
int pid = fork(); // 创建子进程
if (pid == 0) {   // 子进程
	exec_status = exec("calc", argc, argv0, argv1, ...);
	printf("Why would I execute?");
} else { // 父进程。合理设计:else if (pid > 0)
	printf("Whose your daddy?");
	...
	child_status = wait(pid);
}
if (pid < 0) { /* error occurred */

执行完exec()后,pid的id变化了,open files的路径也改变了

在实际内存中的布局图:
执行完exec()后,PCB中的代码段完全被新的程序calc所替换,且执行地址发生了变化

5. fork的开销

fork()的实现开销

  • 对子进程分配内存
  • 复制父进程的内存和CPU寄存器到子进程(有一个寄存器例外)
  • 开销昂贵!!

在99%的情况下,我们在调用fork()之后调用exec()

  • fork()操作中内存复制是没有作用的
  • 子进程将可能关闭打开的文件和连接

03 等待和退出

等待和退出是父子进程之间的一种交互,完成子进程的资源回收

wait()系统调用:用于父进程等待子进程的结束,子进程结束时通过exit()向父进程返回一个值,父进程通过wait()接受并处理返回值,存在以下几种情况:

  • 子进程存活,父进程进入阻塞等待状态,等待子进程的返回结果,当子进程调用exit()时唤醒父进程,将exit()返回值作为父进程中wait()的返回值

  • 僵尸进程进程等待时(子进程exit()提前退出,变成僵尸进程),wait()立即返回一个值

  • 若无子进程存活是,wait()立刻返回

exit()系统调用:进程的有序终止,进程结束执行时调用exit(),完成进程资源回收,主要有以下几大功能;

  • 将调用参数作为进程的 “结果”

  • 关闭所有打开的资源(文件,连接等等)

  • 释放内存

  • 释放大部分支持进程的操作系统结构

  • 检查是否父进程是存活着的:

    • 若存活:保留结果的值直到僵尸进程需要它,进入僵尸(zombie)状态
    • 如果不存活:释放所有的数据结构,进程结束
  • 清理所有等待的僵死进程

进程终止是最终的垃圾收集(资源回收)

执行exec()时,进程可能处于不同的状态。

线程

为什么引入线程

我们举个例⼦,假设你要编写⼀个视频播放器软件,那么该软件功能的核心模块有三个:

  • 从视频⽂件当中读取数据;
  • 对读取的数据进⾏解压缩;
  • 把解压缩后的视频数据播放出来;

对于单进程的实现⽅式,都会是以下这个⽅式:

对于单进程的这种方式,存在以下问题:

  • 播放出来的画面和声音会不连贯,因为当 CPU 能力不够强的时候, Read 的时候可能进程就等在这了,这样就会导致等半天才进行数据解压和播放;
  • 各个函数之间不是并发执行,影响资源的使用效率;

那改进成多进程的方式:

对于多进程的这种方式,依然会存在问题:

  • 进程之间如何通信,共享数据?
  • 维护进程的系统开销较大,如创建进程时,分配资源、建立 PCB;终止进程时,回收资源、撤销PCB;进程切换时,保存当前进程的状态信息;

那到底如何解决呢?需要有⼀种新的实体,满足以下特性:

  • 实体之间可以并发运行
  • 实体之间共享相同的地址空间

这个新的实体,就是 线程( Thread),线程之间可以并发运行且共享相同的地址空间。

线程的概念

线程是进程当中的一条执行流程
线程是进程的一部分,描述指令流执行状态。它是进程中的指令执行流的最小单元,是CPU调度的基本单位。

同一个进程内多个线程之间可以共享代码段、数据段、打开的⽂件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。

线程的优缺点?

线程的优点:

  • ⼀个进程中可以同时存在多个线程;
  • 各个线程之间可以并发执行;
  • 各个线程之间可以共享地址空间和⽂件等资源;

线程的缺点:

  • 当进程中的⼀个线程崩溃时,会导致其所属进程的所有线程崩溃

线程与进程的比较

进程线程的比较如下:

  • 进程是资源(包括内存、打开的⽂件等)分配的单位,线程是 CPU 调度的单位;
  • 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;
  • 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系;
  • 线程能减少并发执行的时间和空间开销;

对于,线程相比进程能减少开销,体现在:

  • 线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们;
  • 线程的终止时间比进程快,因为线程释放的资源相比进程少很多;
  • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同⼀个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较⼤的;
  • 由于同⼀进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更⾼了;

线程的上下文切换

线程与进程最⼤的区别在于:线程是CPU调度的基本单位,而进程则是资源分配的基本单位

所以,所谓操作系统的任务调度,实际上的调度对象是线程,⽽进程只是给线程提供了虚拟内存、全局变量等资源。

对于线程和进程,我们可以这么理解:

  • 当进程只有⼀个线程时,可以认为进程就等于线程;

  • 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下⽂切换时是不需要修改的;

另外,线程也有自己的私有数据,比=如栈和寄存器等,这些在上下文切换时也是需要保存的。

线程上下文切换的是什么?

这还得看线程是不是属于同一个进程:

  • 当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换⼀样;

  • 当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据;线程是进程当中的一条执行流程

所以,线程的上下文切换相比进程,开销要小很多

线程的实现

主要有三种线程的实现方式:

  • 用户线程User Thread):在用户空间实现的线程,不是由内核管理的线程,是由⽤户态的线程库来完成线程的管理;
  • 内核线程Kernel Thread):在内核中实现的线程,是由内核管理的线程;
  • 轻量级进程LightWeight Process):在内核中来⽀持用户线程;

那么,这还需要考虑一个问题,用户线程和内核线程的对应关系:

首先,第一种关系是多对一的关系,也就是多个⽤户线程对应同一个内核线程:

第二种是一对一的关系,也就是一个用户线程对应一个内核线程:

第三种是多对多的关系,也就是多个⽤户线程对应到多个内核线程:

1. 用户线程
  用户线程是基于用户态的线程管理库来实现的,那么线程控制块 TCB 也是在库里面来实现的,对于操作系统而言是看不到这个 TCB 的,它只能看到整个进程的 PCB。

  所以,用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。

用户线程的 特征/优点

  • 不依赖与操作系统的内核,内核不感知用户线程的存在,可用于不支持线程的多进程操作系统

  • 在用户空间实现的线程机制,每个进程有私有的线程控制块(TCB)列表,TCB由线程库函数维护

  • 同一进程内的用户线程切换速度快,无需要用户态 / 核心态切换

  • 允许每个进程拥有自己的线程调度算法

用户线程的缺点

  • 线程发起系统调用而阻塞时,则整个进程进入等待状态

  • 不支持基于线程的处理机抢占,除非当前运行线程主动放弃,它所在进程的其他线程无法抢占CPU

  • 只能按进程分配CPU时间,多个线程进程中,每个线程的时间片较少

2. 内核线程
  内核线程是由操作系统管理的,线程对应的 TCB 自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责。

内核线程的优点

  • 由内核维护 PCB 和 TCB
  • 线程执行系统调用而被阻塞不影响其他线程
  • 以线程为单位进行CPU时间分配,多线的进程可获得更多的CPU时间。

内核线程的缺点

  • 线程的创建、终止和切换相对较大,通过系统调用 / 内核函数,在核内实现

3. 轻量级线程

  轻量级进程(Light-weight process , LWP)是内核⽀持的用户线程,一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的,也就是 LWP 都是由一个内核线程支持。

在大多数系统中,LWP与普通进程的区别也在于它只有⼀个最小的执行上下文和调度程序所需的统计信息。

在 LWP 之上也是可以使用用户线程的,那么 LWP 与用户线程的对应关系就有三种:

  • 1 : 1 ,即⼀个 LWP 对应 ⼀个用户线程;
  • N : 1 ,即⼀个 LWP 对应多个用户线程;
  • M : N ,即多个 LMP 对应多个用户线程;

LWP 模型:

1 : 1 模式

⼀个线程对应到⼀个 LWP 再对应到⼀个内核线程,如上图的进程 4,属于此模型。

  • 优点:实现并行,当⼀个 LWP 阻塞,不会影响其他 LWP;
  • 缺点:每⼀个用户线程,就产生⼀个内核线程,创建线程的开销较⼤。

N : 1 模式

  多个用户线程对应⼀个 LWP 再对应⼀个内核线程,如上图的进程 2,线程管理是在用户空间完成的,此模式中用户的线程对操作系统不可见。

  • 优点:用户线程要开几个都没问题,且上下文切换发生用户空间,切换的效率较⾼;
  • 缺点:一个用户线程如果阻塞了,则整个进程都将会阻塞,另外在多核 CPU 中,是没办法充分利用CPU 的。

M : N 模式

  根据前面的两个模型混搭⼀起,就形成 M:N 模型,该模型提供了两级控制,首先多个用户线程对应到多个 LWP,LWP 再一一对应到内核线程,如上图的进程 3。

  • 优点:综合了前两种优点,大部分的线程上下文发生在用户空间,且多个线程又可以充分利用多核CPU 的资源。

组合模式

  如上图的进程 5,此进程结合 1:1 模型和 M:N 模型。开发⼈员可以针对不同的应用特点调节内核线程的数目来达到物理并行性和逻辑并行性的最佳方案。

学习整理自【清华大学】操作系统 + 【小林Coding】图解系统

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

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

相关文章

航空电子FC节点卡, FC交换机,主要采用LC或MPO光纤接口形式

FC节点卡主要采用LC或MPO光纤接口形式&#xff0c;可以作为4/2个独立端口使用&#xff0c;也可以作为2对/1对冗余端口使用&#xff0c;支持1.0625Gbps、2.125Gbps、4.25Gbps、8.5Gbps通信速率。节点卡完全遵循FC-LS&#xff0c;FC-FS&#xff0c;FC-AE-ASM、FC-AE-1553B等FC光纤…

特斯拉擎天柱机器人:工厂自动化的未来

随着技术的进步&#xff0c;工业自动化已经逐步进入了一个新的纪元。特斯拉最近公布的擎天柱机器人Optimus的演示&#xff0c;不仅仅展示了一个高科技机器人的能力&#xff0c;更是向我们揭示了未来工厂的可能性。 特斯拉擎天柱机器人的功能展示 马斯克在最新的演示中向我们展…

《米小圈动画古诗》—“诗情画意”也不是很难嘛!

创新是一个民族的灵魂和希望&#xff0c;是一个国家兴旺发达的不竭动力&#xff0c;而学习古诗词就是丰富孩子想象力、培养学生创新精神最有效的方法。因为&#xff0c;诗的韵律&#xff0c;情绪跌宕&#xff0c;可以让孩子在大脑中形成一幅完整的图画。 诗歌带给人最美妙的体…

2024首届香港多元文化暨人工智能国际旗袍选美比赛在香港启动

4月30日&#xff0c;2024首届香港多元文化暨人工智能国际旗袍选美比赛在香港帝京酒店正式启动&#xff0c;本次是英雄电影娱乐有限公司创新的旗袍文化选美项目。除了旗袍文化选美&#xff0c;还有中国悠久的“香道文化和茶道文化”融合一起&#xff0c;将中国的多元文化与旗袍文…

MT3032 环形喂猪

思路&#xff1a; 1.输出Error的情况&#xff1a;m>n/2 2.首先将饥饿值放到大根堆中&#xff0c;先喂最饿的猪i&#xff0c;则把i的饥饿值加到sum中&#xff1b;但也又可能喂i-1和i1&#xff0c;所以此时需要反悔&#xff1a;把i取出来的同时&#xff0c;将a[i-1]a[i1]-a…

学SQL啦

3 SQL 3.1 SQL查询语言 新手学习网址&#xff1a;https://sqlzoo.net/wiki/SQL_Tutorial SQL查询语句语法结构和运行顺序 语法结构&#xff1a;select--from--where--group by--having--order by--limit运行顺序&#xff1a;from--where--group by--having--order by--limit-…

C语言----杨辉三角

各位看官们好。学习到这里想必大家应该对C语言的了解也是很深刻的了吧。但是我们也不能忘记我们一起学习的知识啊。在我们以前学习C语言的时候我想大家应该都听说过杨辉三角吧。虽然我们把其中的规律找到那么这个代码就简单很多了。那么接下里我们就来讲讲杨辉三角。 首先我们先…

如何设置cPanel的自动备份

近期我们购买了Hostease美国VPS云主机产品&#xff0c;由于需要设置服务器的自动备份&#xff0c;我们向Hostease技术团队进行了咨询&#xff0c;他们提到VPS云主机的cPanel面板包含自动备份功能&#xff0c;下面我们就介绍如何进行自动备份的设置。 首先你需要登录到WHM面板&…

2024蓝桥杯CTF writeUP--缺失的数据

压缩包的内容 里面有secret.txt文件&#xff0c;用ARCHPR工具套上字典&#xff0c;爆破压缩包密码。密码为pavilion 解压得到原图&#xff0c;并且有了加密后的图片&#xff0c;根据代码里的key和参数直接运行脚本解密水印图片&#xff1a; import cv2 import numpy as np imp…

一文扫盲(10):考试管理系统的功能模块和界面设计

一、什么是考试管理系统 考试管理系统是一种用于管理和组织考试过程的软件系统。它提供了一系列功能&#xff0c;包括考试计划安排、考试报名、考生管理、试卷管理、考试监控、成绩管理等。考试管理系统的目的是简化和自动化考试流程&#xff0c;提高考试的效率和准确性。 考试…

启动配置 BOOT

在STM32F10xxx里&#xff0c;可以通过BOOT[1:0]引脚选择三种不同启动模式。 STM32微控制器实现了一个特殊的机制&#xff0c;系统可以不仅仅从Flash存储器或系统存储器启动&#xff0c;还可以从内置SRAM启动。 根据选定的启动模式&#xff0c;主闪存存储器、系统存储器或SRAM可…

微信小程序 手机号授权登录

手机号授权登录 效果展示 这里面用的是 uni-app 官方的登录 他支持多端发布 https://zh.uniapp.dcloud.io/api/plugins/login.html#loginhttps://zh.uniapp.dcloud.io/api/plugins/login.html#login 下面是代码 <template><!-- 授权按钮 --><button v-if&quo…

怎样给excel表格加密?如何有效的防止文件被他人你查看

在处理敏感信息或共享机密数据时&#xff0c;为 Excel 工作簿中的表格添加密码保护是一种重要的安全措施。当我们需要处理大量的工作簿并保护其中的表格时&#xff0c;手动逐个添加密码可能变得繁琐且耗时。因此&#xff0c;我们需要一种批量添加密码保护的方法。本文将详细介绍…

时钟模块RX8025SA 内置32.768 kHz石英晶体振荡器

实时时钟模块RX8025SA&#xff0c;料号Q41802552000100&#xff0c;是一款低功耗&#xff0c;高精度时钟芯片。时钟芯片RX8025SA选型过程中应该注意哪些&#xff1f;RX8025SA又应用在哪些领域呢&#xff1f;爱普生RTC实时时钟RX8025SA&#xff0c;内置32.768 kHz石英晶体振荡器…

【话题】如何看待AI技术,以及AI技术的发展现状和未来趋势

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 背景一、引言二、AIGC技术的发展现状2.1、技术突破与成果2.2、应用领域的拓展2.3、市场规模的增长 三、AIGC技术的未来趋势3.1、技术融合与创新3.2、应用领域的深化3.3、…

软件测试小妙招:详细解读 postman接口测试导入导出操作

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 postman中的集合脚本&#xff0c;环境变量、全局变量全部都可以导出&#xff0c;然后分享给团队…

追踪攻击数据包中的真实IP地址:方法与技巧

在网络安全领域&#xff0c;追踪攻击数据包中的真实IP地址是一项至关重要的任务。通过确定攻击者的真实IP地址&#xff0c;可以有效地识别和阻止网络攻击行为&#xff0c;提高网络安全防御水平。IP数据云IP地址查询将介绍几种常用的方法和技巧&#xff0c;帮助安全人员有效追踪…

命令行方式将mysql数据库迁移到达梦数据库(全步骤)

因项目需求&#xff0c;需要将mysql数据库转换为国产达梦数据库&#xff0c;但由于安全问题&#xff0c;正式环境只能用命令行方式连接&#xff0c;下列是操作全步骤 目录 一、操作逻辑二、操作步骤1、本地安装达梦相关工具2、将服务器mysql导出到本地a) 服务器命令行导出mysql…

数据中台:企业数字化转型的驱动力量_光点科技

在当今数字化快速发展的时代&#xff0c;企业正积极寻求转型升级的新路径。在这个过程中&#xff0c;数据中台以其独特的功能和价值&#xff0c;逐渐成为了企业数字化转型的关键驱动力。本文将深入探讨数据中台的角色、架构及其在企业中的应用&#xff0c;以期为企业的数字化转…

java多线程编码应用1——java多线程CompletableFuture使用技巧

在实际项目开发过程中&#xff0c;大部分程序的执行顺序都是按照代码编写的先后顺序&#xff0c;依次从上往下挨个执行的&#xff0c;但是对于统计或者批量操作数据时&#xff0c;是否有更好的方案呢&#xff1f;这时候就可以考虑使用多线程编程&#xff0c;异步并行执行多个任…