操作系统进程同步

news2025/1/11 2:18:51

文章目录

  • 操作系统进程同步
    • 一.进程同步的基本概念
      • 1.两种形式的制约关系
      • 2.临界资源(critical resource)
      • 3.临界区(critical section)
      • 4.同步进制遵循的原则
    • 二.硬件同步机制
      • 1.关中断
      • 2.Test-and-Set 指令
      • 3.Swap指令实现进程互斥
    • 三.信号量机制
      • 1.整型信号量
      • 2.记录型信号量
      • 3.AND型信号量
      • 4.信号量集
    • 四.信号量的应用
      • 1.进程互斥
      • 2.前趋关系
    • 五.管程机制

操作系统进程同步

一.进程同步的基本概念

进程同步机制的主要任务是对多个相关进程在执行次序上进行协调,使并发执行的多个进程之间按照一定的规则共享系统资源,并能很好地相互合作,从而使程序的执行具有可再现性。

1.两种形式的制约关系

(1)间接相互制约关系
由于共享系统资源,如CPU,IO设备等而致使这些并发执行的程序之间形成的相互制约关系。

(2)直接相互制约关系
由于进程之间相互合作而产生的制约关系,例如输入进程A和计算进程B,共享一个缓冲区,输入进程A向缓冲区输入数据,当缓冲区为空时,计算进程B由于不能获得所需数据而被阻塞。

2.临界资源(critical resource)

多个进程需要互斥访问的共享资源,如打印机,磁带机等。

3.临界区(critical section)

每个进程中访问临界资源的那段代码称为临界区。若能保证多个进程互斥地进入自己的临界区,就可以实现对临界资源的互斥访问。
while(true)
{
进入区 :用于检查欲访问的临界资源是否正在被其他进程访问
临界区:访问临界资源,将临界区设置为正在被访问的标志
退出区:将临界区正在被访问的标志恢复为未被访问的标志
剩余区:其他部分代码
}

4.同步进制遵循的原则

  • 空闲让进:当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立刻进入自己的临界区,以有效利用临界资源。
  • 忙则等待:当已有进程进入临界区时,表明临界资源正在被访问,因而其他试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。
  • 有限等待:对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入”死等“状态。
  • 让权等待:当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入”忙等“状态。

二.硬件同步机制

1.关中断

在进入锁测试之前关闭中断,直到完成锁测试并上锁之后才能打开中断。进程在临界区执行期间,计算机系统不响应中断,从而不会引发调度,也就不会发生进程或线程的切换。由此保证了对锁测试和关锁操作的连续性和完整性,有效保证了互斥。

关中断的缺陷
①滥用关中断权力可能导致严重后果。
②关中断时间过长影响系统效率,限制了处理器交叉执行程序的能力。
③关中断方法不适用于多CPU系统,在一个处理器上关中断不能阻止进程在其他处理器上执行相同的临界段代码。

2.Test-and-Set 指令

借助硬件指令——“测试并建立”指令TS(Test-and-Set)以实现互斥的方法。

  • 这条指令可以看作为一个函数过程,其执行过程是不可分割的,是一条原语。
  • lock有两种状态:*lock=FALSE时,表示该资源空闲;当 *lock=TRUE时,表示该资源正在被使用。
boolean TS(boolean *lock)
{
   boolean old;
   old=*lock;
   *lock=TRUE;
   return old;
}

使用TS指令管理临界区时,为每个临界资源设置一个布尔变量lock,lock可以看成是临界资源的一把锁,只有当lock的值为FALSE时该临界资源才能被访问,并且lock的初值也是FALSE。
该TS函数的执行过程可以描述为:

  • 将锁的状态*lock复制到变量old中,变量old代表原来锁的状态
  • 将锁lock赋值为TRUE,等效于将锁关闭,使临界资源不能被访问
  • 返回保存了锁原本状态的布尔变量old

利用TS指令实现互斥的循环进程结构可描述如下:

do{
  ...
  while(TS(&lock));
  critical section;//临界区
  lock=FALSE;      //退出区
  remainder section;//剩余区
}
  • 首先在进入临界区之前,需要不断用TS指令来测试锁的状态,只有当测试结果为锁开,即lock=FALSE时,才能进去临界区
  • 在执行完临界区程序后,需要将锁打开,即将lock赋值FALSE,以便别的进程正常访问临界资源

3.Swap指令实现进程互斥

该指令称为对换指令,再Intel 80x86中称为XCHG指令,用于交换两个字的内容

void swap(boolean *a,boolean *b)
{
  boolean temp;
  temp=*a;
  *a=*b;
  *b=temp;
}

对换指令可以简单有效地实现互斥,方法是为每一个临界资源设置一个全局布尔变量lock,初始值为FALSE,在每个进程中再利用一个局部布尔变量key,利用交换lock和key的值来检测锁的状态并保证锁的关闭。

利用swap指令实现进程互斥的循环进程可描述如下:

do{
  key=TRUE;
  do{
     swap(&lock,&key);
    }while(key!=FALSE);
    临界区操作;
    lock=FALSE;
    ...
  }while(TRUE);
  • 首先将变量key赋值为TRUE,即可以让锁关闭的状态
  • 之后循环交换lock和key的值,将lock锁的状态交换到key并同时将key的值TRUE交换给锁,即每一次交换之后锁的状态始终是关闭的,防止其他进程中途访问临界资源。
  • 只有当从key得到锁的状态是FALSE,即锁被打开的状态时,才允许进行下面的临界区操作。
  • 当临界区操作执行完毕后,再将lock锁赋值为FALSE,即打开锁来让其他进程正常访问

三.信号量机制

1.整型信号量

最初有Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准原子操作(Atomic Operation):wait(s),signal(s) 访问,很长时间以来,这两个操作一直被分别称为P,V操作。

Wait(S)
{
    while(S<=0);
    S--;
 }
signal(S)
{
   S++;
}
  • wait(S)和signal(S)是两个原子操作,在执行时是不可中断的,当某个进程在修改某信号量S时,没有其他进程可以同时对该信号量进行修改
  • 在wait(S)中,对S值的测试和S - -的操作都不可中断
  • wait(S)操作中,只要信号量S<=0就会不断进行测试,所以该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”状态。

2.记录型信号量

记录型信号量机制中S->value的初值表示系统中某类资源的数目,因而又称为资源信号量
记录型信号量采取了“让权等待”策略而不存在“忙等”现象
但是会有多个进程等待访问同一临界资源的情况
所以在记录型信号量机制中除了需要一个表示资源数目的变量value外,还需要增加一个进程链表指针list,用于链接上述所有等待的进程。
记录型信号量是由于它采用了记录型的数据结构而得名的。

信号量semaphore变量的数据结构可描述如下:

typedef struct{
    int value;
    struct process_control_block *list;
    }semaphore;

记录型信号量机制下的wait操作

wait(semaphore *S){
    S->value--;
    if(S->value<0) block(S->list);
    }
  • 每次wait操作意味着该进程请求一个单位的该类资源,使系统中可供分配的该类资源数目减少一个
  • 当S->value<0时,表示该类资源已无可分配,因此进程调用block原语进行自我阻塞,放弃处理机,并插入到信号量链表S->list中。

记录型信号量机制下的signal操作

signal(semaphore *S){
    S->value++;
    if(S->value<=0) wakeup(S->list);
    }
  • 每次signal操作表示执行进程释放一个单位资源,使系统中可供分配的该类资源数目增加一个
  • 若加1后仍有S->value<=0,则表示该信号量链表中仍有等待该资源的进程被阻塞,故应该调用wakeup原语,将S->list链表中的第一个等待进程唤醒。
  • 若S->value的初值为1,则表示只允许一个进程访问临界资源,此时信号量转化为互斥信号量,用于进程互斥。

3.AND型信号量

AND型信号量的引入原因:
AND型信号量针对一个进程需要获得两个或更多的共享资源后方能执行任务的场合。
假定两个进程A和B,它们都要求访问共享数据D和E,共享数据都应作为临界资源。为此,可为这两个数据分别设置用于互斥的信号量Dmutex和Emutex,并令它们的初值都为1。相应的,在两个进程中都应包含对Dmutex和Emutex的操作,即:

Process A:
wait(Dmutex);
wait(Emutex);

Process B:
wait(Dmutex);
wait(Emutex);

若进程A和B按下述次序交替执行wait操作:

process A: wait(Dmutex); //于是Dmutex=0
process B: wait(Emutex); //于是Emutex=0
process A: wait(Emutex); //于是Emutex=-1 进程A阻塞
process B: wait(Dmutex); //于是Dmutex=-1 进程B阻塞

此时进程A和B进入死锁状态,当进程同步时要求的共享资源越多时,发生死锁的可能性就越大。

AND型信号量的思想:
AND同步机制的基本思想是,将进程在整个运行过程中所需的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。只要有一个所需资源未能分配给该进程,其他可以分配给该进程的资源也不对该进程进行分配。
即对若干临界资源的分配采取原子操作,要么全部分配要么一个也不分配。

AND型信号量进制的实现
Swait操作:

Swait(S1,S2,...,Sn)
{
    while(TRUE)
    {
      if(Si>=1&&...&&Sn>=1)
      {
       for(i=1;i<=n;i++) Si--;
       break;
      }
      else{
      place the process in the waiting queue associated with the first Si found with Si<1,and set the program count of this process to the beginning of Swait operation
      将进程放入与Si<1的第一个Si相关联的等待队列中,并将此进程的程序计数设置为Swait操作的开始 
      }
    
   }
}

Ssignal操作:

Ssignal(S1,S2,...,Sn){
    while(TRUE)
    {
      for(i=1;i<=n;i++)
      {
        Si++;
        Remove all the process waiting in the queue associated with Si into the ready queue
        将与Si相关联的队列中等待的所有进程移到就绪队列中
      }
    }
}

4.信号量集

  • 对AND型信号量机制进行扩充,对进程所申请的所有资源以及每类资源不同的资源需求量,在一次P,V原语操作中完成申请或释放。
  • 进程对信号量的测试值不再是1,而是该类资源的分配下限值ti,即要求Si>=ti,否则不进行分配。
  • 当允许分配时,进程对该类资源的需求值为di,即表示资源占用量,进行Si=Si-di操作,而不是Si=Si-1.
  Swait(S1,t1,d1,...,Sn,tn,dn); 
  Ssignal(S1,d1,...,Sn,dn);

四.信号量的应用

1.进程互斥

semaphore mutex = 1; // mutex 取值为 -1,0,1
  • mutex=1时表示两个进程皆未进入需要互斥的临界区
  • mutex=0时表示有一个进程进入临界区运行,另外一个进程必须等待,挂入阻塞队列
  • mutex=-1时表示有一个进程正在临界区运行,另一个进程因等待而阻塞在信号量队列中,需要被当前已在临界区运行的进程退出时唤醒。
PA()
{
while(1)
{
wait(mutex);
  临界区;
signal(mutex);
  剩余区;
}
}
PB()
{
while(1)
{
wait(mutex);
  临界区;
signal(mutex);
  剩余区;
}
}
  • 在利用信号量机制实现进程互斥时应该注意,wait(mutex)和signal(mutex)应该成对出现。
  • 缺少wait(mutex)将会导致系统混乱,不能保证对临界资源的互斥访问
  • 缺少signal(mutex)将会使临界资源永远不被释放,从而使等待该资源而阻塞的进程不能被唤醒。

2.前趋关系

假设有两个进程P1和P2。P1中有语句S1,P2中有语句S2.希望S2在S1之后执行。
为实现上述前驱关系,需要使进程P1和P2共享一个公用信号量S,并赋初值为0,将signal(S)操作放在语句S1后面,并在S2语句前面插入wait(S)操作。

P1中:

S1;
signal(S);

P2中:

wait(S);
S2;
  • 初始状态下S=0,P2先执行会阻塞
  • 只有当P1执行完后,通过wait(S)原语使S+1后S的值为1时,P2才能执行S2语句

利用信号量机制实现如下较复杂的前趋图:

在这里插入图片描述

p1(){S1;signal(a);signal(b)}
p2(){wait(a);S2;signal(c);signal(d);}
p3(){wait(b);S3;signal(e);}
p4(){wait(c);S4;signal(f);}
p5(){wait(d);S5;signal(g);}
p6(){wait(e);wait(f);wait(g);S6;}
main()
{
  semaphore a,b,c,d,e,f,g;
  a.value=b.value=c.value=d.value=e.value=f.value=g.value=0;
  cobegin
    p1();p2();p3();p4();p5();p6();
  coend
}

五.管程机制

信号量机制的缺点:(管程的引入) 在信号量机制中,每个要访问临界资源的进程都必须自备同步操作wait(S)和signal(S)。这就使大量的同步操作分散在各个进程中。不仅给系统的管理带来了麻烦,而且还会因同步操作的使用不当而导致系统死锁。

管程的定义: 代表共享资源和数据结构以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序共同构成了一个操作系统的资源管理模块,我们称之为管程。管程被请求和释放资源的进程所调用。Hansan为管程所下的定义是:“一个管程定义了一个数据结构和能为并发进程所执行在该数据结构上的一组操作,这组操作能同步进程和改变管程中的数据。”
管程由四部分组成:

  • ①管程的名称
  • ②局部于管程的共享数据结构说明
  • ③对该数据结构进行操作的一组过程
  • ④对局部与管程的共享数据设置初始值的语句

在这里插入图片描述

⭐管程的特点:

  • 管程包含了面向对象的思想,它将表征共享资源的数据结构及其对数据结构操作的一组过程,包括同步机制,都集中并封装在一个对象内部,隐藏了实现细节。

  • 封装于管程内部的数据结构仅能被封装于管程内部的过程所访问,任何管程外的过程都不能访问它;反之,封装于管程内部的过程只能访问管程内部的数据结构。

  • 所有进程访问临界资源时,都只能通过管程间接访问,而管程每次只准许一个进程进入管程,执行管程内的过程,从而实现进程互斥。

    概括来讲,管程的主要特性有:

    • ①模块化:是基本程序单位,可单独编译
    • ②抽象数据类型:即包含数据,也包含对数据的操作
    • ③信息掩蔽:管程内数据只能被管程内过程访问,内部数据结构和过程对外不可见

⭐条件变量

为什么需要条件变量(条件变量的引入): 当一个进程调用了管程,在管程中被阻塞或挂起,直到阻塞或挂起的原因接触,在此期间如果该进程不释放管程,则别的进程无法进入管程而被迫长时间等待。为了解决这个问题,引入了条件变量condition。

条件变量的定义:

  • 由于进程被阻塞或挂起的原因可有多个,所以设置多个条件变量,对这些条件变量的访问只能在管程中进行。管程中每个条件变量都用condition x,y的形式进行说明
  • 每个条件变量保存了一个链表,用于记录因该条件变量而阻塞的所有进程
  • 条件变量是抽象数据类型,对条件变量的操作仅仅是wait和signal。
    • x.wait:正在调用冠层的进程因x条件需要被阻塞或挂起,则调用x.wait将自己插入到x条件的等待队列上,并释放管程,直到x条件发生变化。
    • x.signal:正在调用管程的进程发现x条件发生了变化,则调用x.signal,重新启动一个因x条件而阻塞或挂起的进程,如果存在多个这样的进程,则选择其中一个,如果没有,继续执行原进程,而不产生任何结果。(这与信号量机制中的signal操作不同,因为后者总是要执行s=s+1操作,因而总会改变信号量的状态)

管程的语法描述如下:

Monitor monitor_name{ //管程名

share variable declarations; //共享变量说明

cond declarations;           //条件变量说明

public:                      //能被进程调用的过程

void P1(......)              //对数据结构操作的过程
{......}
void P2(......)
{......}
......
  void(......)
  {......}
  ......

  {                         //管程主体
  initalization code;       //初始化代码
  ......
  }
}



}

管程与进程的联系和区别:

  • ①虽然二者都定义了数据结构,但进程定义的是私有数据结构PCB,管程定义的是公共数据结构,如消息队列等;
  • ②二者都存在对各自数据结构上的操作,但进程是由顺序程序执行有关操作,而管程主要是进行同步操作和初始化操作;
  • ③设置进程的目的在于实现系统的并发性,而管程的设置则是解决共享资源的互斥使用问题;
  • ④进程通过调用管程中的过程对共享数据结构实行操作,该过程就如通常的子程序一样被调用,因而管程为被动工作方式,进程为主动工作方式。
  • ⑤进程之间能并发执行,而管程则不能与其调用者并发;
  • ⑥进程具有动态性,由“创建”而诞生,由“撤销”而消亡,而管程则是操作系统中的一个资源模块(静态),供进程调用。

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

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

相关文章

mysql-视图的定义和简单使用

mysql-视图视图1. 视图的定义2.视图的创建规则和使用限制小结视图 1. 视图的定义 视图是虚拟的表。与包含数据的表不一样&#xff0c;视图只包含使用时动态检索数据的查询。 视图的一些常见应用&#xff1a; 重用SQL语句。 简化复杂的SQL操作。在编写查询后&#xff0c;可以…

c语言之链表

今天来介绍一下c语言如何手写一个单向链表&#xff0c;我们都知道链表是用来提高空间的利用效率的数据结构&#xff0c;其中包括了一个数据域和指针域&#xff0c;数据域用来存储数据&#xff0c;指针域用来指向下一个节点。数据结构如下 我们都知道数据结构最主要的是他的增删…

从底层入手搞定C++引用和内联函数

C引用和内联函数 文章目录C引用和内联函数一、引用1.1引用的概念1.1.1代码展示1.1.2图示1.2引用的特性1.3常引用1.4引用的使用场景1.5 传值、传引用效率比较1.6 引用和指针的区别二、内联函数2.1.内联函数的概念2.2内联函数的特性总结一、引用 首先我们来看一下引用的概念&…

每天10个前端小知识 【Day 2】

前端面试基础知识题 1. arguments 这种类数组&#xff0c;如何遍历类数组&#xff1f; for(var i 0, len arrayLike.length; i < len; i) { …… }使用ES6的 … 运算符&#xff0c;我们可以轻松转成数组。 function func(...arguments) { console.log(arguments); // […

蓝牙和射频技术的关系

蓝牙和射频技术的关系 提到蓝牙大家的比较熟悉&#xff0c;但射频技术很多都没有明白什么意思&#xff1f; 现简单介绍下他们的关系&#xff0c;让想了解射频技术的朋友更清楚。 1&#xff1a;定义&#xff1a; 射频&#xff08;RF&#xff09;是Radio Frequency的缩写&#xf…

Fluent的模型参数化(2)

前言&#xff1a;本文基于2023R1版本。在《Fluent的模型参数化&#xff08;1&#xff09;》中&#xff0c;对将Fluent模型进行参数化的方法进行了概述。本文主要基于已参数化的模型&#xff0c;进行参数分析的方法。基本概念&#xff1a;输入参数&#xff1a;工况的设置数据&am…

SpringMVC之入门案例

目录 一&#xff1a;概述 二代码实操&#xff1a; 步骤1:创建Maven项目&#xff0c;并导入对应的jar包 步骤2:创建控制器类 步骤3:创建配置类 步骤4:创建Tomcat的Servlet容器配置类 步骤5:配置Tomcat环境 步骤6:启动运行项目 步骤7:浏览器访问 知识点1&#xff1a;Co…

Cesium的设计结构与零基础入门

关于cesium我最近会写一系列的文章教程,带大家一步一步的从零开始学习cesium,看过我的文章的人都清楚我的讲课方式就是从一个小白的视角,从一个什么都不懂的视角,一点一点的循序渐进为大家讲清楚一个知识,好废话不多说我们开始! 首先在学习之前,你必须清楚cesium是个什…

DynaSLAM-7 DynaSLAM中双目运行流程(Ⅰ):加载Mask R-CNN网络部分MaskNet.cc

目录 1.执行流程 2. SegmentDynObject::SegmentDynObject 3. SegmentDynObject::GetSegmentation 1.执行流程 我们输入到命令行五个参数&#xff1a; stereo_kitti path_to_vocabulary path_to_settings path_to_sequence (path_to_masks) 分别是DynaSLAM双目例程中的可执行…

血氧仪/额温枪/电子体温计等 LED数显/数码管显示驱动控制电路(IC/芯片)-VK1S68C资料 SSO24小体积封装,FAE技术支持

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1S68C 封装形式&#xff1a;SSOP24 概述&#xff1a; VK1S68C是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有3线串行接口、数据锁存器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极…

Go 项目(一)

目录基础环境包管理编码规范命名规范注释import 规范错误处理RPC内置 RPC改协议改调用基础 基础部分参考这个系列接下来的这部分是对上面的更新和重构&#xff0c;更加深入理解框架部分 环境 基础环境&#xff0c;主要在Linux上搞&#xff1b;最主要是 docker&#xff0c;do…

Mac 可以玩游戏吗,有哪些游戏可以玩?

Mac 可以玩游戏吗&#xff0c;有哪些游戏可以玩&#xff1f; 新款的 MacBook Pro 入手有一段时间了&#xff0c;期间一直在熟悉 MacOS 系统及日常工作使用&#xff0c;一直都听说 MacBook 是工作本&#xff0c;不得不说工作使用确实很强&#xff0c;但用的久了就还是特别想折腾…

flex 布局:实现一行固定个数,超出强制换行(流式布局)

一、flex 布局基础知识 flex 布局的知识想必不用多说&#xff0c;一些常用的属性如下&#xff1a; 设置在父容器上的属性&#xff1a;display&#xff1a;flex&#xff0c; align-items, justify-content, flex-wrap。 设置在子容器上的属性&#xff0c;通过 flex: 1&#x…

最终一致分布式事务方案解析

业来主流的分布式事务的解决方案主要归位两大类&#xff1a;强一致性分布式事务和最终一致性分布式事务&#xff0c;本文不对强一致性分布式事务做过多描述&#xff0c;主要针对最终一致性方案解析。 根据笔者的工作经验来看&#xff0c;最终一致性方案适用用大部分互联网场景…

SpringBoot 2.7.8 自定义 Starter 自动配置

文章目录SpringBoot 2.7.8 自定义 Starter前言本次练习的代码仓库代码简要说明custom-springboot-starter-demo 的pom文件customer-starter 的pom文件test 的pom文件配置类配置信息SpringBoot 2.7.8 自定义 Starter 前言 前段时间&#xff0c;SpringBoot 出 3.x 版本了。听说…

如何与他人交流 (如何跟老板提涨工资) 第16章

最重要的事情 ---强有力的论证上期我们说根据场景来优化策略,是在隔靴搔痒,然而一个容易给出理由的人很容易成为演讲的高手.说服别人的理性与感性举个例子&#xff0c;我们如果说服别人买一件商品。采用打广告的形式&#xff0c;往往有两种途径。比如说我们要买一辆车。展示它的…

Power BI瀑布图

瀑布图&#xff08;Waterfall Plot&#xff09;也被称为阶梯图&#xff0c;它出现的历史并不长&#xff0c;最初为麦肯锡所创&#xff0c;因自上而下形似瀑布而得名&#xff0c;面世之后以其展示效果清晰而流畅被广为接受&#xff0c;经常在经营和财务分析中使用。 瀑布图是根…

4d view软件 .vol .4dv转 dcom文件

一、 .vol转 dcom文件 1、4d view软件打开vol文件 2、settings--dicom configuration-add&#xff0c;设置如下&#xff08;前面的alias、ae title等设的可以随便一些&#xff0c;我都设了1&#xff09;&#xff0c;然后save&exit&#xff08;第6步设置也可以&#xff09…

Vue13-计算属性computed

首先使用methods方法实现属性计算 步入正题&#xff1a; 计算属性&#xff1a;拿已有的属性计算得出新的属性 1.vue中属性和计算属性是分开的&#xff0c;属性在data中&#xff0c;计算属性在computed中 computed中计算属性以对象的形式存贮 这里是将fullName以及get的返回值…

计算机网络基础学习指南(一)

前言 计算机网络基础是研发/运维工程师都需掌握的知识&#xff0c;但往往会被忽略。 今天&#xff0c;我将献上一份详细 & 清晰的计算机网络基础学习指南&#xff0c;涵盖 TCP / UDP协议、Http协议、Socket等&#xff0c;希望你们会喜欢。 1. 计算机网络体系结构 1.1 简…