操作系统|day2.进程、线程、协程

news2024/11/14 15:29:06

文章目录

  • 进程
    • 概念
    • 特点
    • 并行和并发
    • 进程之间的通信
    • 进程的状态
    • 进程的调度
      • 基本准则
      • 调度方式
      • 具体算法
    • 特殊进程
  • 线程
    • 概念
    • 线程状态转换
      • 线程状态
      • 线程调度
      • 线程同步
      • 多线程通信
    • 线程池
      • 种类
      • 工作流程
      • 五种状态
      • 拒绝策略
      • 参数
      • 队列大小
  • 协程
    • 概念
    • 优势

进程

概念

进程就是正在运行的程序,它会占用对应的内存区域,由CPU进行执行与计算。(是系统进行资源分配和调度的基本单位,是操作系统结构的基础。)

特点

  1. 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间,在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间

  2. 动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合,程序加入了时间的概念以后,称为进程,具有自己的生命周期和各种不同的状态,这些概念都是程序所不具备的.程序是死的,进程是活的

  3. 并发性:多个进程可以在单个处理器CPU上并发执行,多个进程之间不会互相影响.

并行和并发

并行:指在同一时刻,有多条指令在多个处理器上同时执行,所以无论从微观还是从宏观来看,二者都是一起执行的。
在这里插入图片描述

并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

在这里插入图片描述

异同点:

  1. 相同点:并发和并行的目标都是最大化CPU的使用率,将cpu的性能充分压榨出来。
  2. 不同点:
    • 并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在
    • 并行要求程序能够同时执行多个操作,而并发只是要求程序“看着像是”同时执行多个操作,其实是交替执行。

进程之间的通信

  1. 匿名管道:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  2. 有名管道(FIFO):
    • 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    • 有名管道严格遵循先进先出(first in first out) ,对匿名管道及有名管道的读总是从开始处返回数据,对它们的写则把数据添加到末尾。
    • 有名管道的名字存在于文件系统中,内容存放在内存中。
  3. 信号:
    • 信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
    • 如果该进程当前并未处于执行状态,则该信号就有内核保存起来,知道该进程回复执行并传递给它为止。
    • 如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消是才被传递给进程。
  4. 消息队列:
    • 消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示。
    • 与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。
    • 另外与管道不同的是,消息队列在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。
  5. 共享内存:
    • 进程间本身的内存是相互隔离的,而共享内存机制相当于给两个进程开辟了一块二者均可访问的内存空间,这时,两个进程便可以共享一些数据了。
    • 多进程同时占用资源会带来一些意料之外的情况,这时,我们往往会采用信号量来控制多个进程对共享内存空间的访问。
  6. 信号量
    • 信号量主要用来解决进程和线程间并发执行时的同步问题,进程同步是并发进程为了完成共同任务(采用某个条件来协调他们的活动),这是进程之间发生的一种直接制约关系。
    • 对信号量的操作分为P操作和V操作,P操作是将信号量的值减一,V操作是将信号量的值加一。当信号量的值小于等于0之后,再进行P操作时,当前进程或线程会被阻塞,直到另一个进程或线程执行了V操作将信号量的值增加到大于0之时。锁也是用的这种原理实现的
  7. socket(套接字)
    • 套接字可以看做是:不同主机之间的进程进行双向通信的端点。(套接字 = IP地址 + 端口号)
    • Socket是应用层和传输层之间的桥梁

在这里插入图片描述

进程的状态

在这里插入图片描述

  1. 新建:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态.
  2. 就绪:当一个进程获得了除处理机以外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列。
  3. 运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
  4. 阻塞:也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。
  5. 终止:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行

进程的调度

进程调度是操作系统中非常重要的一个部分,它的主要作用是合理地分配CPU时间,以最大化系统的吞吐量、响应时间和资源利用率。对于具体的进程调度方案,有多种不同的实现方式和算法。

基本准则

  1. CPU利用率
  2. 系统吞吐量:单位时间内CPU完成作业的数量
  3. 周转时间:作业完成时间-作业提交时间
  4. 等待时间:等待时间指进程处于等处理机状态的时间之和,等待时间越长,用户满意度越低。处理机调度算法实际上并不影响作业执行或输入/输出操作的时间,只影响作业在就绪队列中等待所花的时间。因此,衡量一个调度算法的优劣,常常只需简单地考察等待时间。
  5. 响应时间:响应时间指从用户提交请求到系统首次产生响应所用的时间。在交互式系统中,周转时间不可能是最好的评价准则,一般采用响应时间作为衡量调度算法的重要准则之一。从用户角度来看,调度策略应尽量降低响应时间,使响应时间处在用户能接受的范围之内。

调度方式

  1. 非剥夺调度方式
    • 又称非抢占方式。非剥夺调度方式是指当一个进程正在处理机上执行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在执行的进程继续执行,直到该进程完成或发生某种事件而进入阻塞态时,才把处理机分配给更为重要或紧迫的进程。
    • 这种方式的优点是实现简单、系统开销小,适用于大多数的批处理系统,但它不能用于分时系统和大多数的实时系统。
  2. 剥夺调度调度方式
    • 又称抢占方式。剥夺调度方式是指当一个进程正在处理机上执行时,若有某个更为重要或紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给这个更为重要或紧迫的进程。采用剥夺式的调度,对提高系统吞吐率和响应效率都有明显的好处。
    • 但“剥夺”不是一种任意的行为,必须遵循一定的原则,主要有优先权、段进程优先和时间片原则等

具体算法

  1. 先来先服务调度算法(FCFS)

    • FCFS 调度算法是一种最简单的调度算法,它既可用于作业调度,又可用于进程调度。在作业调度中,算法每次从后备作业队列中选择最先进入该队列的一个或儿个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列。
    • FCFS 调度算法的特点是算法简单,但效率低;对长作业比较有利,但对短作业不利(相对SPF和高响应比);有利于CPU繁忙型作业,而不利于I/0繁忙型作业。【跨考解答】:为什么CPU繁忙型是长作业,因为长短是使用CPU的长短,I/O繁忙型使用CPU比较短。
  2. 短进程优先调度算法(SPF)

    • 短作业(进程)优先调度算法是指对短作业(进程)优先调度的算法。短进程优先(SPF) 调度算法从就绪队列中选择一个估计运行时间最短的进程,将处理机分配给它,使之立即执行,直到完成或发生某事件而阻塞时,才释放处理机。(每次调度都选就绪队列中最短的)

    • 缺点:

      • 该算法对长作业不利。更为严重的是,若有一长进程进入就绪队列,由于调度程序总是优先调度那些(即使是后来进来的)短作业,将导致长作业长期不被调度(饥饿)。
      • 该算法完全未考虑作业的紧迫程度,因而不能保证紧追性作业会被及时处理。
      • 由于作业的长短只是根据用户所提供的估计执行时间而定的,而用户又可能会有意或无意地缩短其作业的估计运行时间,致使该算法不一定能真正做到短作业优先调度。

      【注意】 SPF调度算法的平均等待时间、平均周转时间最少。\

  3. 优先级调度算法

    • 在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。
    • 根据新的更高优先级进程能否抢占正在执行的进程,可将该调度算法分为如下两种:
      • 非剥夺式优先级调度算法。当一个进程正在处理机上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在运行的进程继续运行,直到由于其自身的原因而主动让出处理机时(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。
      • 剥夺式优先级调度算法。当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。
    • 而根据进程创建后其优先级是否可以改变,可以将进程优先级分为以下两种:
      • 静态优先级。优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。
      • 动态优先级。在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据有进程占有CPU 时间的长短、就绪进程等待CPU 时间的长短。
    • 优先级设置原则
      • 系统进程>用户进程。系统进程作为系统的管理者,理应拥有更高的优先级。
      • 交互型进程>非交互型进程(或前台进程>后台进程)。大家平时在使用手机时,在前台运行的正在和你交互的进程应该更快速地响应你,因此自然需要被优先处理,即要有更高的优先级。
      • I/0 型进程>计算(CPU)型进程。我们知道, I/0 设备(如打印机)的处理速度要比CPU 慢得多,因此若将I/0 型进程的优先级设置得更高,就更有可能让I/0 设备尽早开始工作,进而提升系统的整体效率。
  4. 时间片轮转调度算法

    • 时间片轮转调度算法主要适用于分时系统。在这种算法中,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程序总是选择就绪队列中的第一个进程执行,即先来先服务的原则,但仅能运行一个时间片,如l00ms 。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。
    • 在时间片轮转调度算法中,时间片的大小对系统性能的影响很大。若时间片足够大,以至于所有进程都能在一个时间片内执行完毕,则时间片轮转调度算法就退化为先来先服务调度算法。若时间片很小,则处理机将在进程间过于频繁地切换,使处理机的开销增大,而真正用于运行用户进程的时间将减少。因此,时间片的大小应选择适当。
    • 时间片的长短通常由以下因素确定:系统的响应时间、就绪队列中的进程数目和系统的处理能力.
  5. 高响应比优先调度算法

    • 高响应比优先调度算法是对FCFS调度算法和SPF调度算法的一种综合平衡,同时考虑了每个作业的等待时间和估计的运行时间。在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。
    • 响应比的变化规律可描述为:响应比=(等待时间+要求服务时间)/要求服务时间
    • 作业的等待时间相同时,要求服务时间越短,响应比越高,有利于短作业。
    • 要求服务时间相同时,作业的响应比由其等待时间决定,等待时间越长,其响应比越高,因而它实现的是先来先服务。
    • 对于长作业,作业的响应比可以随等待时间的增加而提高,等待时间足够长时,其响应比便可升到很高,从而也可获得处理机。因此,克服了饥饿状态,兼顾了长作业。

    先来先服务+短进程算法

  6. 多级反馈队列调度算法

    • 多级反馈队列调度算法是时间片轮转调度算法和优先级调度算法的综合与发展,如下图所示。通过动态调整进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。例如,为提高系统吞吐量和缩短平均周转时间而照顾短进程;为获得较好的I/0 设备利用率和缩短响应时间而照顾I/0 型进程;同时,也不必事先估计进程的执行时间。
      在这里插入图片描述

    • 优点:

      • 终端型作业用户:短作业优先。
      • 短批处理作业用户:周转时间较短。
      • 长批处理作业用户:经过前面几个队列得到部分执行,不会长期得不到处理。
    • 实现:

      • 设置多个就绪队列,并为各个队列赋予不同的优先级,第1 级队列的优先级最高,第2级队列次之,其余队列的优先级逐次降低。
      • 赋予各个队列中进程执行时间片的大小各不相同。在优先级越高的队列中,每个进程的运行时间片越小。例如,第2级队列的时间片要比第1级队列的时间片长1倍。
      • 一个新进程进入内存后,首先将它放入第1 级队列的末尾,按FCFS 原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;若它在一个时间片结束时尚未完成,调度程序便将该进程转入第2 级队列的末尾,再同样按FCFS 原则等待调度执行;若它在第2 级队列中运行一个时间片后仍未完成,再以同样的方法放入第3级队列……
      • 仅当第1 级队列为空时,调度程序才调度第2 级队列中的进程运行;仅当第1~(i-1)级队列均为空时,才会调度第i 级队列中的进程运行。若处理机正在执行第i 级队列中的某进程,这时又有新进程进入优先级较高的队列[第1~(i-1)中的任何一个队列],则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回第i 级队列的末尾,把处理机分配给新到的更高优先级的进程。

特殊进程

  1. 僵尸进程

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。

  1. 孤儿进程

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

子进程是通过父进程创建的,子进程再创建新的进程。子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束。 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。

线程

概念

线程是操作系统OS能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.

一个进程可以开启多个线程,其中有一个主线程来调用本进程中的其他线程。

我们看到的进程的切换,切换的也是不同进程的主线程

多线程可以让同一个进程同时并发处理多个任务,相当于扩展了进程的功能。

线程状态转换

线程状态

线程调度

线程同步

多线程通信

线程池

种类

工作流程

五种状态

拒绝策略

参数

队列大小

详情请看以下文章

进程与线程的区别

  1. 一个线程从属于一个进程;一个进程可以包含多个线程。
  2. 一个线程挂掉,对应的进程挂掉;一个进程挂掉,不会影响其他进程。
  3. 进程是系统资源调度的最小单位;线程CPU调度的最小单位。进程是CPU分配资源的最小单位
  4. 进程系统开销显著大于线程开销;线程需要的系统资源更少。
  5. 进程在执行时拥有独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展段;但每个线程拥有自己的栈段和寄存器组。
  6. 进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈,线程切换时只需要切换硬件上下文和内核栈。
  7. 通信方式不一样。
  8. 进程适应于多核、多机分布;线程适用于多核

在这里插入图片描述

协程

概念

协程是微线程,在子程序内部执行,可在子程序内部中断,转而执行别的子程序,在适当的时候再返回来接着执行。

优势

  1. 协程调用跟切换比线程效率高:协程执行效率极高。协程不需要多线程的锁机制,可以不加锁的访问全局变量,所以上下文的切换非常快。
  2. 协程占用内存少:执行协程只需要极少的栈内存(大概是4~5KB),而默认情况下,线程栈的大小为1MB。
  3. 切换开销更少:协程直接操作栈基本没有内核切换的开销,所以切换开销比线程少。

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

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

相关文章

进阶SpringBoot之 yaml 语法

SpringBoot 使用一个全局的配置文件,名字固定 application.properties 语法结构:keyvalue application.yml 语法结构:key:(空格)value 配置文件的作用是可以修改 SpringBoot 自动配置的默认值 在 res…

【NOI-题解】1022. 百钱百鸡问题1024. 购买文具1249. 搬砖问题1250. 马克思手稿的问题1342. 怎样种树?

文章目录 一、前言二、问题问题:1022. 百钱百鸡问题问题:1024. 购买文具问题:1249. 搬砖问题问题:1250. 马克思手稿的问题问题:1342. 怎样种树? 三、感谢 一、前言 欢迎关注本专栏《C从零基础到信奥赛入门…

无心剑小诗《郑钦文,为您骄傲》

郑钦文,为您骄傲 在赛场上如猎豹出击 每一拍都交织着力量与智慧 郑钦文,您是无畏的勇士 曾经的挫折是砥砺的砂石 今日的辉煌,是拼搏的勋章 今晚,红土上您书写传奇 战胜强敌,您气势如虹 汗水与激情洒满整个赛场 梦想…

49 序列解包的多种形式和用法

序列解包(Sequence Unpacking)是 Python 中非常重要和常用的一个功能,可以使用非常简洁的形式完成复杂的功能,提高了代码的可读性,减少了程序员的代码输入量。 x, y, z 1, 2, 3 # 多个变量同时赋值 v_tuple (False…

openpnp - loc_*.png是没用的临时文件

文章目录 openpnp - loc_*.png是没用的临时文件概述笔记END openpnp - loc_*.png是没用的临时文件 概述 前一段时间将X轴的固定螺母动了,让X轴运动更顺滑些。 不得已,对openpnp设备重新进行了标定。 到底部相机高级矫正完成后,正常退出&…

Datawhale AI 夏令营——AI+逻辑推理——Task3

# Datawhale AI 夏令营 夏令营手册:从零入门 AI 逻辑推理 比赛:第二届世界科学智能大赛逻辑推理赛道:复杂推理能力评估 代码运行平台:魔搭社区 大模型微调 LoRA LoRA(Low-Rank Adaptation)微调是一种…

Linux查看进程和进程号的几种方式

根据进程名查看进程号 1、pidof命令: 2、pgrep命令: 3、ps命令 根据进程号查看进程名: ps命令:

【UE 网络】Gameplay框架在DS架构中的扮演的角色

目录 0 引言1 核心内容1.1 Gameplay各部分创建的流程1.2 Gameplay框架在DS和客户端的存在情况1.3 数据是独立存在于DS和客户端的 2 Gameplay框架各自负责的功能2.1 GameMode2.2 GameState2.3 PlayerController2.4 PlayerState2.5 Pawn2.6 AIController2.7 Actor2.8 HUD2.9 UI &…

JVM:内存结构,直接内存,对象创建,死亡判定

对于从事C、C程序开发的开发人员来说,在内存管理领域,他们既是拥有最高全力的“皇帝”,又是从事最基础工作的劳动人民——既拥有每一个对象的“所有权”,又担负着每一个对象声明从开始到终结的维护责任。对于Java程序员来说&#…

Golang | Leetcode Golang题解之第319题灯泡开关

题目: 题解: func bulbSwitch(n int) int {return int(math.Sqrt(float64(n) 0.5)) }

SSM校园管理系统-计算机毕设定制-附项目源码(可白嫖)48395

摘 要 如今计算机行业的发展极为快速,搭载于计算机软件运行的数据库管理系统在各行各业得到了广泛的运用,其在数据管理方面具有的准确性和高效性为大中小企业的日常运营提供了巨大的帮助。自从2020年新冠疫情爆发以来,防疫成了社会关注的重中…

elementUI 的el-date-picker日期,开始时间不能大于结束时间

需求描述&#xff1a;form表单里有开始日期和结束日期&#xff0c;要求开始日期不能大于结束日期&#xff0c;但是开始日期可以等于结束日期。 效果如下&#xff1a; 实现代码&#xff1a; <el-form ref"form" :model"form" :rules"rules" …

UNI-APP_点击,长按,触摸,结束触摸事件

touchstartEventHandle手指触摸动作开始字节跳动小程序不支持touchmoveEventHandle手指触摸后移动字节跳动小程序不支持touchendEventHandle手指触摸动作结束字节跳动小程序不支持touchcancelEventHandle手指触摸动作被打断&#xff0c;如来电提醒&#xff0c;弹窗字节跳动小程…

errno错误码列举

errno&#xff0c;int变量&#xff0c;表示系统最近一次错误码。 当系统调用和一些库函数发生错误时&#xff0c;会给errno赋值&#xff0c;以指示哪里出了问题。 目录 errno值列表 errno值获取示例 errno值列表 <errno.h>头文件定义了errno的一些值&#xff0c;部分…

Spring MVC框架面试题

目录 一、什么是SpringMVC&#xff1f;简单介绍下你对SpringMVC的理解&#xff1f; 二、SpringMVC的流程&#xff1f; 三、SpringMVC的优点 四、SpringMVC的主要组件 五、SpringMVC怎么样设重定向和转发的&#xff1f; 六、SpringMVC怎么和Ajax相互调用的&#xff1f; 七…

Python酷库之旅-第三方库Pandas(064)

目录 一、用法精讲 251、pandas.Series.tz_localize方法 251-1、语法 251-2、参数 251-3、功能 251-4、返回值 251-5、说明 251-6、用法 251-6-1、数据准备 251-6-2、代码示例 251-6-3、结果输出 252、pandas.Series.at_time方法 252-1、语法 252-2、参数 252-3…

【java】单行注释(//)与多选注释(/* */)

文章目录 单行注释多行注释注意事项 在Java中&#xff0c;注释是用来给代码添加说明的&#xff0c;它不会被编译器执行。Java提供了两种主要的注释方式&#xff1a;单行注释和多行注释&#xff08;有时也称为块注释或块级注释&#xff09;。 单行注释 单行注释以两个正斜杠&…

爬小红book--自定义获取

免责声明:本文仅做分享!!! from DrissionPage import ChromiumPage import time pa str(input("输入关键词&#xff1a;")) pl str(input("输入评论内容&#xff1a;")) page ChromiumPage() page.get(https://www.xiaohongshu.com/search_result?keyw…

php生成xml文件的封装类文件-可生成带缩进格式化的xml文件及关于opcache缓存的操作小工具cachetool的使用

一、php生成xml文件的封装类文件-可生成带缩进格式化的xml文件 最近因为有需要&#xff0c;对生成xml文件进行了一些处理&#xff0c;很早之前使用过SimpleXML加载接口返回的xml数据并处理&#xff0c;这次的使用偏向于XML文件的生成。有一个需求&#xff0c;生成的xml文件格式…

【保姆级讲解下AI绘画自动生成器有哪些?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…