同步异步与阻塞非阻塞的区别 (不定时更新)

同步异步与阻塞非阻塞的概念对于很多初学者来说是一个模糊的概念,其实我们的生活中存在着很多同步和异步的例子。

同步和异步关注的是消息通信机制
在计算机领域,同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。 

举个通俗的例子:

你打电话问书店老板有没有《ECMAScript 6入门》这本书时

如果是同步通信机制,书店老板会说,你稍等,别挂电话,”我查一下",然后开始查啊查,等查好了(可能是1分钟,也可能是一天)告诉你结果(返回结果)。在书店老板查找这个过程,你一直在等待他的回复,这期间你不能去干别的事情。

如果异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。在书店老板查找这个过程,这期间你可以先去干别的事情。

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用:是指调用结果返回之前,当前线程会被挂起。一直处于等待消息通知,不能够执行其他业务,调用线程只有在得到结果之后才会返回。
非阻塞调用:指在不能立刻得到结果之前,该调用不会阻塞当前线程,而会立刻返回。

举个通俗的例子:

同步阻塞:你打电话告诉老板你要买《ECMAScript 6入门》这本书,老板拿起电话听你说完就去查书,没有说话,你什么也不知道,在得到任何结果之前,你一直拿着电话干等,你此时什么也干不了。30分钟后老板直接把书送到你家,这时你才挂断电话。每次电话你都要得到结果(书到家)后你才挂断电话,这是同步。你一直拿着电话等结果,这是阻塞。

同步非阻塞:你打电话告诉老板你要买《ECMAScript 6入门》这本书,老板拿起电话后说“我不知道有没有货,现在去查”便挂了电话,又过了10分种你第二次打电话说你要买《ECMAScript 6入门》这本书,老板拿起电话说完“还没有查到,你再等会儿”便挂断电话。挂断电话5分钟后老板查到有书,但并没有主动打电话告诉你。你再次等待10分钟后第三次电话老板问结果,老板说“书有了,我给你送到家”,你断挂电话。每次电话你都要得得到结果(去查->还没有查到->有货)后你才挂断电话,这是同步。你每隔10分钟打电话询问结果,这是非阻塞。

异步阻塞:你打电话过去问老板有没有《ECMAScript 6入门》这本书,老板说“我不知道有没有货,现在去查,先挂了电话,有结果告诉你,你等我电话”就挂掉电话。等电话期间你什么也不干,老板主动给你发短信通知你结果书有了,5分钟后希望老板现在把书送来,你再次打电话让老板送书,老板马上送书上门。老板主动给你发短信,这是异步。等待老板的短信期间你什么也没干,这是阻塞。

异步非阻塞:你打电话过去后问老板有没有《ECMAScript 6入门》这本书,老板说“好的,有货我直接给你送上门”就挂掉电话。然后你想干嘛干嘛,等老板门到后你看书。等待老板主动给你送书上门,这是异步。挂了电话后你就想干嘛干嘛,这是非阻塞。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
 

 

文章目录
同步(synchronous),异步(asynchronous)
阻塞(blocking),非阻塞(non-blocking)(这里指系统的io操作)
进程,线程,


进程间通信的方式
管道
匿名管道(pipe)
命名管道(FIFO)
消息队列
共享内存
信号
信号量
socket
软链接和硬链接
inode块
软链接接和硬链接
同步(synchronous),异步(asynchronous)
同步:发起一个请求后,如果没有立即返回,就一直等待接收方返回
异步:
发送一个请求,然后立即返回,去干别的事情,请求在接收方以队列形式存在,进行处理,当处理完成之后返回结果

阻塞(blocking),非阻塞(non-blocking)(这里指系统的io操作)
内核态: 当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态,简称为内核态。此时处理器处于特权级最高的(0级)内核代码中执行。

用户态: 当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。

当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态

在Linux环 境下,所有的I/O系统调用默认都是阻塞的。
那么什么叫阻塞?阻塞的系统调用是指,当进行系统调用时,除非出错(被信号打断也视为出错),进程将会一直陷入内核态直到调用完成。(不能再干自己的事)
非阻塞的系统调用是指无论I/O操作成功与否,调用都会立刻返回。

同步和异步,阻塞非阻塞
同步与异步主要从通信的角度出发:例如你去食堂买饭,窗口有很多种。有的窗口是你买了饭需要在那里等着,他立即给你打饭,这是同步。有的窗口是你买了饭,他会给你一个号牌,你不用在窗口等着,你可以去干其它的事,等饭做好了,,会叫号通知你,这是异步。

阻塞与非阻塞主要从进程/线程和系统调用的角度出发:典型例子如如spring框架下传统的Spring MVC的Servlet Stack;


这两对概念很相似,不用特意区分,理解就行。脱离场景说不同没有意义,

在I/O操作中,同步既可以是阻塞的,也可以是非阻塞的,而常用的Linux的I/O调用实际上都是同步的。这里的同步和非同步,是指I/O数据的复制工作是否同步执行。

以系统调用read为例。阻塞的read会一直陷入内核态直到read返回;而非阻塞的read在数据未准备好的情况下,会直接返回错误,而当有数据时,非阻塞的read 同样会一直陷入内核态,直到read完成。这个read就是同步的操作,即I/O的完成是在当前执行流程下同步完成的。

一共可以组成四种通信方式
同步阻塞方式,发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。比如,在超市排队付账时,客户(发送方)向收款员(接收方)付款(发送请求)后需要等待收款员找零,期间不能做其他的事情;而收款员等待收款机返回结果(IO)操作后才能把零钱取出来交给客户(响应请求),期间也只能等待,不能做其他事情。这种方式实现简单,但是效率不高。

同步非阻塞方式,发送方向接收方发送请求后,一直等待响应;接收方处理请求时进行的IO操作如果不能马上得到结果,就立即返回,去做其他事情,但由于没有得到请求处理结果,不响应发送方,发送方一直等待。一直到IO操作完成后,接收方获得结果响应发送方后,接收方才进入下一次请求过程。在实际中不使用这种方式。

异步阻塞方式,发送方向接收方发送请求后,不用等待响应,可以接着进行其他工作;接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。这种方式在实际中也不使用。

异步非阻塞方式,发送方向接收方发送请求后,不用等待响应,可以继续其他工作;接收方处理请求时进行的IO操作如果不能马上得到结果,也不等待,而是马上返回去做其他事情。当IO操作完成以后,将完成状态和结果通知接收方,接收方再响应发送方。继续使用在超市排队付账的例子。客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他事情,比如打电话、聊天等;而收款员在等待收款机处理交易(IO操作)的过程中还可以帮助客户将商品打包,当收款机产生结果后,收款员给客户结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种。

进程,线程,
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。
说得简单点,下面这段代码执行的时候

int main() 
{
    printf(”pid is %d/n”,getpid() );
    return 0;
}
1
2
3
4
5
进入main函数,这就是一个进程,进程pid会打印出来,然后运行到return,该函数就退出,然后由于该函数是该进程的唯一的一次执行,所以return后,该进程也会结束
从不同的角度得到的结果不同


作者:zhonyong
链接:https://www.zhihu.com/question/25532384/answer/81152571
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先来一句概括的总论:进程和线程都是一个时间段的描述,是CPU工作时间段的描述。
下面细说背景:
CPU+RAM+各种资源(比如显卡,光驱,键盘,GPS, 等等外设)构成我们的电脑,但是电脑的运行,实际就是CPU和相关寄存器以及RAM之间的事情。

一个最最基础的事实:CPU太快,太快,太快了,寄存器仅仅能够追的上他的脚步,RAM和别的挂在各总线上的设备完全是望其项背。那当多个任务要执行的时候怎么办呢?轮流着来?或者谁优先级高谁来?不管怎么样的策略,一句话就是在CPU看来就是轮流着来。

一个必须知道的事实:执行一段程序代码,实现一个功能的过程介绍 ,当得到CPU的时候,相关的资源必须也已经就位,就是显卡啊,GPS啊什么的必须就位,然后CPU开始执行。这里除了CPU以外所有的就构成了这个程序的执行环境,也就是我们所定义的程序上下文。当这个程序执行完了,或者分配给他的CPU执行时间用完了,那它就要被切换出去,等待下一次CPU的临幸。在被切换出去的最后一步工作就是保存程序上下文,因为这个是下次他被CPU临幸的运行环境,必须保存。

串联起来的事实:前面讲过在CPU看来所有的任务都是一个一个的轮流执行的,具体的轮流方法就是:先加载程序A的上下文,然后开始执行A,保存程序A的上下文,调入下一个要执行的程序B的程序上下文,然后开始执行B,保存程序B的上下文。。。。

========= 重要的东西出现了========
进程和线程就是这样的背景出来的,两个名词不过是对应的CPU时间段的描述,名词就是这样的功能。
进程就是包换上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文
线程是什么呢?
进程的颗粒度太大,每次都要有上下的调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成 a,b,c等多个块组合而成。那么这里具体的执行就可能变成:
程序A得到CPU =》CPU加载上下文,开始执行程序A的a小段,然后执行A的b小段,然后再执行A的c小段,最后CPU保存A的上下文。
这里a,b,c的执行是共享了A的上下文,CPU在执行的时候没有进行上下文切换的。这里的a,b,c就是线程,也就是说线程是共享了进程的上下文环境,的更为细小的CPU时间段。

到此全文结束,再一个总结:

进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。


通常我们也称进程为heavy-weight process,线程为light-weight process
但是我想从计算机的发展史角度来说一下进程和线程,或许更好理解其中的不同,在早期计算机是没有线程这么一说的,进程就是最基本的运行单位,包含静态的资源和动态的计算,特意将动态和静态两个词语强调了一下,是因为随着计算机性能的提升,和系统设计的改进,为了避免进程间调度带来的资源开销,同时提升系统的并发性能,于是在进程中引入了线程的概念,专门来负责程序的动态部分。
以现在的windows系统为例,线程专门来描述系统的动态计算,是系统调度和运行的基本单位,而现在的进程已经是一种静态的概念,可以理解成为一个或多个线程提供共享资源的上下文容器,更多强调的是系统的资源,包括memory及设备的统称,已经不再强调动态特性,而这些动态的特性已经被转移到线程身上。
所以可以简单总结为

进程是一个资源的容器,为进程里的所有线程提供共享资源,是对程序的一种静态描述
2.线程是计算机最小的调度和运行单位,是对程序的一种动态描述
作者:AndyChen
链接:https://www.zhihu.com/question/25532384/answer/381776755
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。

因此现在大多使用的是多线程技术(值得一提的是,有的多线程是假的多线程,并没有充分利用多核cpu的资源,所有线程在一个核运行,进行切换。比如Python里的多线程是假的多线程,不管有多少核,同一时间只能在一个核中进行操作!利用Python的多线程,只是利用CPU上下文切换的优势,看上去像是并发,其实只是个单线程)

联系与区别
a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
c.调度和切换:线程上下文切换比进程上下文切换要快得多
d.一个程序可以有不止一个的进程
e.一个进程可以没有线程,作为空进程存在,但是由于里面没有线程,cpu在这里无法得到执行,cpu的执行依附于线程
f.线程无法脱离进程而存在

进程间通信的方式
管道
当从一个进程连接数据流到另一个进程时,我们使用管道。通常是把一个进程的输出通过管道连接到另一个进程的输入。用过Linux的人都使用过shell,不可避免地会使用管道进行一些数据的分析和处理,命令格式如下(通常通过符号“|"来使用管道):cmd1 | cmd2
例如:ps -ef | grep mysql

它是一种半双工[^1]的通信方式,数据只能单向流动。

在串行通信中,数据通常是在两个终端(如电脑和外设)之间进行传送,根据数据流的传输方向可分为3种基本传送方式:单工、半双工和全双工。
1、单工
单工就是指A只能发信号,而B只能接收信号,通信是单向的.例如电脑控制打印机,遥控器控制空调,都是单工模式
2、半双工
半双工就是指A能发信号给B,B也能发信号给A,但这两个过程不能同时进行。最典型的例子就象我们在影视作品中看到的对讲机一样:
007:呼叫总部,请求支援,OVER
总部:收到,增援人员将在5分钟内赶到,OVER
007:要5分钟这么久?!要快呀!OVER
在这里,每方说完一句话后都要说个OVER,然后切换到接收状态,同时也告之对方——你可以发言了。如果双方同时处于收状态,或同时处于发状态,便不能正常通信了。    
3、全双工
全双工比半双工又进了一步。在A给B发信号的同时,B也可以给A发信号。典型的例子就是打电话。
A:我跟你说呀……
B:你先听我说,情况是这样的……
A和B在说的同时也能听到对方说的内容,这就是全双工

匿名管道(pipe)
通常所说的管道指的是匿名管道
管道如何实现进程间的通信

(1)父进程创建管道,得到两个⽂件描述符指向管道的两端,fd[1]的输出是fd[0]的输入。
(2)父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道。
(3)父进程关闭fd[0],子进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只支持单向通信)。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。


匿名管道只能用于有亲缘关系的进程,如父进程和子进程,以及兄弟进程间的通信。
随进程的开始而开始,随进程的结束而结束。
管道是有容量大小的

命名管道(FIFO)
匿名管道在不相关的的进程之间交换数据带来了不方便。命名管道则是来解决不相关进程间的通信问题。其通信方式是类似的。

试想这样一个问题,如果有多个进程同时向同一个FIFO文件写数据,而只有一个读FIFO进程在同一个FIFO文件中读取数据时,会发生怎么样的情况呢,会发生数据块的相互交错?

解决的方法是将写操作进行原子化,当要写入的数据量不大于管道空闲缓冲区时,要么全部写入,要么全部不写。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入挂起状态,直到当缓冲区中能够容纳要写入的字节数时,才开始进行一次性写操作。

消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。

(1)消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.
(2)消息队列允许一个或多个进程向它写入与读取消息.
(3)管道和命名管道都是通信数据都是先进先出的原则。
(4)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。

一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相反的,进程向其中写消息时,管道和FIFO必需已经打开来读,那么内核会产生SIGPIPE信号。 IPC的持续性不同。管道和FIFO是随进程的持续性,当管道和FIFO最后一次关闭发生时,仍在管道和FIFO中的数据会被丢弃。消息队列是随内核的持续性,即一个进程向消息队列写入消息后,然后终止,另外一个进程可以在以后某个时刻打开该队列读取消息。只要内核没有重启,消息队列没有被删除。

posix

System V

共享内存
共享内存模型会建立起一块供协作进程共享的内存区域,进程通过向此共享区域读出或写入数据来交换信息。
共享内存有两种实现方式:1、内存映射 2、共享内存机制
1、内存映射
内存映射 memory map机制使进程之间通过映射同一个普通文件实现共享内存,通过mmap()系统调用实现。普通文件被映射到进程地址空间后,进程可以
像访问普通内存一样对文件进行访问,不必再调用read/write等文件操作函数。

2、UNIX System V共享内存机制
IPC的共享内存指的是把所有的共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。

不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程


我们需要确保一个进程在写的时候不能进行操作,但是共享内存本身并没有这种机制,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取,所以我们通常需要用其他的机制来同步对共享内存的访问,例如信号量

信号
信号是Linux系统中的异步通信机制,通知接收信号的进程有某种事件发生,也可以看作是异步通知。由于信号是异步的,进程不必等待信号的到达,事实上,它也不知道信号何时会到达。

信号一般是由系统中一些特定事件引起的,主要包括如下。
1.硬件故障
2.程序运行中的错误,例如除数为0,或者访问进程以外的内存区域。
3.进程的子程序终止
4.用户从终端向进程发送终止等信号
5.进程调用kill,raise,以及alarm等函数向其他进程发送信号。

值得注意的是不是所有错误都会产生信号,只有那些在程序的任何位置都可能发生的错误,才会产生信号,报告错误的发生。

进程收到信号后,对于特定的信号,例如SIGKILL,处理方式是确定的,对于大部分信号,进程可以选择不同的响应方式:
1.捕获信号,这类似于中断处理程序,对于需要处理的信号,进程可以指定相应的函数来进行处理。
2.忽略信号,对信号不进行处理,就像未收到一样,有两个信号不能忽略,即SIGKILL和SIGSTOP信号。
3.让Linux内核执行与信号对于的默认动作,对于大部分信号而言,默认的处理方式是终止相应的程序

部分信号

SIGHUP (挂起) 当运行进程的用户注销时通知该进程,使进程终止

SIGINT (中断) 当用户按下时,通知前台进程组终止进程

SIGQUIT (退出) 用户按下或时通知进程,使进程终止

SIGILL (非法指令) 执行了非法指令,如可执行文件本身出现错误、试图执行数据段、堆栈溢出

SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用

SIGABRT (异常中止) 调用abort函数生成的信号

SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.

SIGFPE (算术异常) 发生致命算术运算错误,包括浮点运算错误、溢出及除数为0.

SIGKILL (确认杀死) 当用户通过kill -9命令向进程发送信号时,可靠的终止进程

SIGUSR1 用户使用

SIGSEGV (段越界) 当进程尝试访问不属于自己的内存空间导致内存错误时,终止进程

SIGUSR2 用户使用

SIGPIPE 写至无读进程的管道, 或者Socket通信SOCT_STREAM的读进程已经终止,而再写入。

SIGALRM (超时) alarm函数使用该信号,时钟定时器超时响应

SIGTERM (软中断) 使用不带参数的kill命令时终止进程

SIGCHLD (子进程结束) 当子进程终止时通知父进程

SIGCONT (暂停进程继续) 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞.

SIGSTOP (停止) 作业控制信号,暂停停止(stopped)进程的执行. 本信号不能被阻塞, 处理或忽略.

SIGTSTP (暂停/停止) 交互式停止信号, Ctrl-Z 发出这个信号

信号量
信号量,也称为信号灯,主要用来控制多个进程对共享资源的访问,信号量是进程通信的一种重要方法,但是它本身并不进行数据交换,这点和前面介绍的管道和消息队列不同。
分类
整型信号量(integer semaphore):信号量是整数,
当小于等于零时,会不断测试是否有资源
记录型信号量(record semaphore):每个信号量s除一个整数值s.value(计数)外,还有一个进程等待队列s.L,其中是阻塞在该信号量的各个进程的标识
二进制信号量(binary semaphore):只允许信号量取0或1值

记录型信号量
信号量的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,进程调用进行自我阻塞,加入到等待队列中

信号量操作    语义
将信号量的值设为某个绝对值    初始化资源个数
信号量加上某个值    释放n个资源
信号量减去某个值    申请n个资源,资源不够则陷入阻塞状态
信号量的值<=0    没有可分配的资源
信号来解决多个进程对同一资源的访问竞争的问题,使在任一时刻只能有一个执行线程访问代码的临界区域,也可以说它是协调进程间的对同一资源的访问权,也就是用于同步进程的

socket
上面所述的通信方式都是在本地进行通信的,如果是不同主机的进程需要通信,就要通过网络的
套接字scoket。
先来了解一下七层模型


<1> 应用层
OSI参考模型中最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP等。
实际公司A的老板就是我们所述的用户,而他要发送的商业报价单,就是应用层提供的一种网络服务,当然,老板也可以选择其他服务,比如说,发一份商业合同,发一份询价单,等等。
<2> 表示层
表示层提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。如果必要,该层可提供一种标准表示形式,用于将计算机内部的多种数据格式转换成通信中采用的标准表示形式。数据压缩和加密也是表示层可提供的转换功能之一。
由于公司A和公司B是不同国家的公司,他们之间的商定统一用英语作为交流的语言,所以此时表示层(公司的文秘),就是将应用层的传递信息转翻译成英语。同时为了防止别的公司看到,公司A的人也会对这份报价单做一些加密的处理。这就是表示的作用,将应用层的数据转换翻译等。
<3> 会话层
会话层就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
会话层的同事拿到表示层的同事转换后资料,(会话层的同事类似公司的外联部),会话层的同事那里可能会掌握本公司与其他好多公司的联系方式,这里公司就是实际传递过程中的实体。他们要管理本公司与外界好多公司的联系会话。当接收到表示层的数据后,会话层将会建立并记录本次会话,他首先要找到公司B的地址信息,然后将整份资料放进信封,并写上地址和联系方式。准备将资料寄出。等到确定公司B接收到此份报价单后,此次会话就算结束了,外联部的同事就会终止此次会话。
<4> 传输层
传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。我们通常说的,TCP UDP就是在这一层。端口号既是这里的“端”。
传输层就相当于公司中的负责快递邮件收发的人,公司自己的投递员,他们负责将上一层的要寄出的资料投递到快递公司或邮局。
<5> 网络层
本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一层就是我们经常说的IP协议层。IP协议是Internet的基础。
网络层就相当于快递公司庞大的快递网络,全国不同的集散中心,比如说,从深圳发往北京的顺丰快递(陆运为例啊,空运好像直接就飞到北京了),首先要到顺丰的深圳集散中心,从深圳集散中心再送到武汉集散中心,从武汉集散中心再寄到北京顺义集散中心。这个每个集散中心,就相当于网络中的一个IP节点。
<6> 数据链路层
将比特组合成字节,再将字节组合成帧,使用链路层地址 (以太网使用MAC地址)来访问介质,并进行差错检测。
数据链路层又分为2个子层:逻辑链路控制子层(LLC)和媒体访问控制子层(MAC)。
MAC子层处理CSMA/CD算法、数据出错校验、成帧等;LLC子层定义了一些字段使上次协议能共享数据链路层。 在实际使用中,LLC子层并非必需的。
这个没找到合适的例子
<7> 物理层
实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。
快递寄送过程中的交通工具,就相当于我们的物理层,例如汽车,火车,飞机,船。


TCP/IP五层模型


什么是socket呢?我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。


socket通信过程


软链接和硬链接
inode块
理解inode,要从文件储存说起。
文件存储在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个个扇区的读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取的最小单位。“块”的大小,最常见的是4KB,即连续八个sector组成一个block。
文件数据都储存在“块”中,那么很显然,我们还必须找到一个地方储存文件的“元信息”,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点“。
每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

软链接接和硬链接
接下来就是要说的软硬链接。
软链接:ln -s 源文件 目标文件
硬链接:ln 源文件 目标文件

可以看到软链接文件的大小和创建时间和源文件不同。软链接文件只是维持了从软链接到源文件的指向关系,相当于Windows里的快捷方式,删除源文件软链接就不能用了
硬链接则是相当于给inode节点创建了一个别名

源文件和硬链接指向的是同一个inode节点,也就是指向的同一个文件。单独的删除源文件或者硬链接也不会对另一个产生影响。只是相当于删除了一个别名
 

参考:

https://blog.csdn.net/qq_38128179/article/details/86132731

https://blog.csdn.net/zhengdeshifeng/article/details/98218421

你可能感兴趣的:(网络编程)