linux while的嵌套怎么用

linux while的嵌套怎么用,第1张

是问shell script?

while [ 条件 ] #如果满足条件就执行do下面的内容

do

......

done

嵌套就是在do里面再加一层while循环,比如

while [ $i -le 10 ]

do

while[ $j -le $i ]

do

command list......

j=$(($j+1))

done

i=$(($i+1))

done

阻塞和非阻塞

对于一个套接字的 I/O通信,它会涉及到两个系统对象,一个是调用这个IO的进程或者线程,另一个就是系统内核。比如当一个读 *** 作发生时,它会经历两个阶段:

①等待数据准备 (Waiting for the data to be ready)

②将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)

阻塞,在Linux中,默认情况下所有的socket都是blocking,当用户进程调用了recvfrom/recv这个系统调用,啮合就开始了IO的第一个阶段:准备数据。但是很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP/TCP包),这个时候内核就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当内核一直等到数据准备好了,它就会将数据从内核中拷贝到用户内存,然后直到返回结果,用户进程才解除阻塞的状态,重新运行起来。

所以,阻塞IO的特点就是在IO执行的两个阶段都被阻塞了。

调用阻塞IO会一直阻塞对应的进程直到 *** 作完成,而非阻塞IO在内核还准备数据的情况下会立刻返回。

阻塞

因此我们给出阻塞的简单定义,阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。

有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。 例如,我们在socket中调用recv函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息,所以我们应该说我们的线程现在是阻塞的。

快递的例子:比如到你某个时候到A楼一层(假如是内核缓冲区)取快递,但是你不知道快递什么时候过来,你又不能干别的事,只能死等着。但你可以睡觉(进程处于休眠状态),因为你知道快递把货送来时一定会给你打个电话(假定一定能叫醒你)。

非阻塞

非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

还是等快递的例子:如果用忙轮询的方法,每隔5分钟到A楼一层(内核缓冲区)去看快递来了没有。如果没来,立即返回。而快递来了,就放在A楼一层,等你去取。

对象的阻塞模式和阻塞函数调用

对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状 态,在适当的时候调用阻塞函数,就可以避免阻塞。而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。我们经常使用的函数select就是这样的一个例子。

同步与异步

首先我们给出POSIX的定义

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes

An asynchronous I/O operation does not cause the requesting process to be blocked1212

同步

用我们的话说,所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事,而只有当所有的工作按照顺序执行完之后,才会返回调用的位置,继续往下执行。

这个很好理解,我们一般做的函数调用,都是同步的,我们的程序按照我们既定的顺序一步一步执行,在前一个 *** 作返回后,我们根据 *** 作的结果,进行下一个阶段的处理,这就是一个同步的过程。

异步

异步,异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。

简单来说

一个同步接收的方式,在这个端口下如果同是来了两个客户端请求,第一个连接得到响应,与服务端建立通讯,而第二个请求就会被一直阻塞直到第一个请求完成 *** 作,各个请求之间就好像排个队,顺序执行,这就是同步。

而一个异步接收方式,就是同时来两个或者多个请求,服务端就同时响应多个客户端,同时给他们连接。各个客户端与服务器的通讯是并行的,一个客户端不必等另一个客户端完成 *** 作。

两者的区别就在于同步IO做IO *** 作的时候会将process阻塞

其实阻塞IO,非阻塞IO,以及我们后面会提到IO复用都属于同步 IO。有人可能会说,非阻塞IO并没有被阻塞啊。这里有个非常“狡猾”的地方,定义中所指的”IO operation”是指真实的IO *** 作,比如非阻塞IO在执行recvfrom这个系统调用的时候,如果内核的数据没有准备好,这时候不会阻塞进程。但是,当内核中数据准备好的时候,recvfrom会将数据从内核拷贝到用户内存中,在这段时间内,进程是被阻塞的。而异步IO则不一样,当进程发起IO *** 作之后,就直接返回再也不理睬了,直到内核发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被阻塞。

我们可以总结为一下几点

同步 就是我调用一个功能,该功能没有结束前,我死等结果。只能顺序执行。

异步 就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知),往往用回调函数或者其他类方式实现。

阻塞 就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。

非阻塞 就是调用我(函数),我(函数)立即返回,而当我准备完毕时,通过select通知调用者。

同步IO和异步IO的区别就在于:数据拷贝的时候进程是否可以被阻塞

阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否能立即返回

并发与迭代

套接字编程经常使用在客户/服务器编程模型(简称C/S模型)中,C/S模型根据复杂度分为简单的客户/服务器模型和复杂的客户/服务器模型。

C/S简单客户/服务器模型是一对一关系,一个服务器端某一时间段内只对应处理一个客户端的请求,迭代服务器模型属于此模型。

C/S复杂服务器模型是一对多关系,一个服务器端某一时间段内对应处理多个客户端的请求,并发服务器模型属于此模型。

迭代服务器模型和并发服务器模型是socket编程中最常见使用的两种编程模型。

通常来说大多数TCP服务器是并发的,大多数UDP服务器是迭代的

比如我们通常在做聊天室的时候,使用UDP协议来发送消息,但是在用户需要上传下载数据的时候,我们通常在服务器和客户端之间建立一个TCP连接来传送文件。。。

但是如果服务一个客户请求的时间不长,使用迭代服务器没有太大问题,一旦客户请求的时间需要花费很长,不希望整个服务器被单个客户长期占用,而希望同时服务多个客户,就需要选择并发服务器了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7220365.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存