科学知识:同步、异步、阻塞和非阻塞区别

简单点说:

阻塞就是干不完不准回来,一直处于等待中,直到事情处理完成才返回;
非阻塞就是你先干,我先看看有其他事没有,一发现事情被卡住,马上报告领导。

我们拿最常用的send和recv两个函数来说吧...
比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据传输(Copy)到TCP/IP协议栈的输出缓冲区,它执行成功并不代表数据已经成功的发送出去了,如果TCP/IP协议栈没有足够的可用缓冲区来保存你Copy过来的数据的话...这时候就体现出阻塞和非阻塞的不同之处了:对于阻塞模式的socket send函数将不返回直到系统缓冲区有足够的空间把你要发送的数据Copy过去以后才返回,而对于非阻塞的socket来说send会立即返回WSAEWOULDDBLOCK告诉调用者说:"发送操作被阻塞了!!!你想办法处理吧..."

对于recv函数,同样道理,该函数的内部工作机制其实是在等待TCP/IP协议栈的接收缓冲区通知它说:嗨,你的数据来了.对于阻塞模式的socket来说如果TCP/IP协议栈的接收缓冲区没有通知一个结果给它它就一直不返回:耗费着系统资源....对于非阻塞模式的socket该函数会马上返回,然后告诉你:WSAEWOULDDBLOCK---"现在没有数据,回头在来看看"

扩展:

在进行网络编程时,我们常常见到同步、异步、阻塞和非阻塞四种调用方式。这些方式彼此概念并不好理解。下面是我对这些术语的理解。

1、同步

所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。最常见的例子就是SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。

2、异步

异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。以 CAsycSocket类为例(注意,CSocket从CAsyncSocket派生,但是起功能已经由异步转化为同步),当一个客户端通过调用 Connect函数发出一个连接请求后,调用者线程立刻可以向下运行。当连接真正建立起来以后,socket底 层会发送一个消息通知该对象。这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。可以使用哪一种依赖于执行部件的实现,除非执行部件提供 多种选择,否则不受调用者控制。如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循 环去检查某个变量的值,这其实是一种很严重的错误)。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知 没太多区别。
3、阻塞

阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等同起来,实际上它们是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。例如,我们在CSocket中调用Receive函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中调用,其实主界面还是应该可以刷新。socket接收数据的另外一个函数recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。

4、非阻塞

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

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

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

(0)

相关推荐

  • Python的Tornado框架实现异步非阻塞访问数据库的示例

    tornado即是一个http非阻塞服务器, 就要用起来, 我们将用到tornado框架 ,mongodb数据库 以及motor(mongodb的异步驱动).来简单实现tornado的非阻塞功能. 其他环境支持的下载与安装 1.安装mongodb $ sudo apt-get install update $ sudo apt-get install mongodb 2.安装motor $ pip install motor 非阻塞 # conf.py import os import moto

  • 200行自定义python异步非阻塞Web框架

    Python的Web框架中Tornado以异步非阻塞而闻名.本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow. 一.源码 本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的Web框架,其中便是众多异步非阻塞Web框架内部原理. #!/usr/bin/env python # -*- coding:utf-8 -*- import re import socket import select import time class HttpResponse(object)

  • java 同步、异步、阻塞和非阻塞分析

    java 同步.异步.阻塞和非阻塞分析 概要: 正常情况下,我们的程序以同步非阻塞的方式在运行.但是我们的程序总会出现一些耗时操作,比如复杂的计算(找出1到10亿之间的素数)和程序本身无法控制的操作(IO操作.网络请求).包含这些耗时操作的方法我们可以把它称为阻塞方法,包含这些耗时操作的任务我们可以把它称为阻塞任务.阻塞与非阻塞是以是否耗时来定义的. 如果程序中存在大量阻塞操作,就会影响程序性能.但是阻塞的存在是客观事实,我们的程序是无法改变它的,一个网络请求需要3秒才能响应,我们不可能让它1毫

  • 详解socket阻塞与非阻塞,同步与异步、I/O模型

    socket阻塞与非阻塞,同步与异步 1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就是在c端发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 异步的概念和同步相对.当c端一个异步

  • 浅谈socket同步和异步、阻塞和非阻塞、I/O模型

    在进行网络编程时,常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式 同步/异步主要针对C端: 同步:c端发出一个功能调用时,在没有得到结果之前,c端死等结果 例如:普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:c端一个异步过程调用发出后,调用者不会立刻得到结果.实际处理这个调用的部件在完成后,通过状态.通知和回调来通知调用者. 例如:ajax请求(异步): 事件触发->服务

  • 科学知识:同步、异步、阻塞和非阻塞区别

    简单点说: 阻塞就是干不完不准回来,一直处于等待中,直到事情处理完成才返回: 非阻塞就是你先干,我先看看有其他事没有,一发现事情被卡住,马上报告领导. 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据传输(Copy)到TCP/IP协议栈的输出缓冲区,它执行成功并不代表数据已经成功的发送出去了,如果TCP/IP协议栈没有足够的可用缓冲区来保存你Copy过来的数据的话...这时候就体现出阻塞和非阻塞的不同之处了:

  • java 中同步、异步、阻塞和非阻塞区别详解

    java 中同步.异步.阻塞和非阻塞区别详解 简单点说: 阻塞就是干不完不准回来,一直处于等待中,直到事情处理完成才返回: 非阻塞就是你先干,我先看看有其他事没有,一发现事情被卡住,马上报告领导. 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据传输(Copy)到TCP/IP协议栈的输出缓冲区,它执行成功并不代表数据已经成功的发送出去了,如果TCP/IP协议栈没有足够的可用缓冲区来保存你Copy过来的数据的话

  • 简述JAVA同步、异步、阻塞和非阻塞之间的区别

    同步和异步,阻塞和非阻塞是大家经常会听到的概念,但是它们是从不同维度来描述一件事情,常常很容易混为一谈. 1. 同步和异步 同步和异步描述的是消息通信的机制. 同步 当一个request发送出去以后,会得到一个response,这整个过程就是一个同步调用的过程.哪怕response为空,或者response的返回特别快,但是针对这一次请求而言就是一个同步的调用. 异步 当一个request发送出去以后,没有得到想要的response,而是通过后面的callback.状态或者通知的方式获得结果.可

  • 一篇文章理解阻塞、非阻塞、同步、异步

    目录 理解阻塞.非阻塞.同步.异步 阻塞 非阻塞 同步 异步 总结 理解阻塞.非阻塞.同步.异步 首先说明,这些都是在特点场景下或者相对情况的词汇,OK,接下来开门见山. 阻塞 可以很直观的理解,就如节假日高速路出口收费站一样,上图片: 9个收费亭,同时来了一大波车,这时候同一时刻只能有9辆车在收费,剩下的车都在只能在后面排队等待,这就是现实中很直观的阻塞现象.这9个收费亭,就是一个瓶颈,或许画为这样更符合大家对瓶颈二字的理解: 第1张图中,高速公路源源不断的车辆到来,和第二张图的效果其实表示一

  • 处理java异步事件的阻塞和非阻塞方法分析

    前言 由于多核系统普遍存在,并发性编程的应用无疑比以往任何时候都要广泛.但并发性很难正确实现,用户需要借助新工具来使用它.很多基于 JVM 的语言都属于这类开发工具,Scala 在这一领域尤为活跃.本系列文章将介绍一些针对 Java 和 Scala 语言的较新的并发性编程方法. 在任何并发性应用程序中,异步事件处理都至关重要.事件来源可能是不同的计算任务.I/O 操作或与外部系统的交互.无论来源是什么,应用程序代码都必须跟踪事件,协调为响应事件而采取的操作. Java 应用程序可采用两种基本的异

  • php 多进程编程父进程的阻塞与非阻塞实例分析

    本文实例讲述了php 多进程编程父进程的阻塞与非阻塞.分享给大家供大家参考,具体如下: php中进程的阻塞,主要是父进程等待子进程退出. 1.php代码如下: <?php //定义进程数量 define('FORK_NUMS', 5); //用于保存进程pid $pids = array(); //我们创建5个子进程 for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die

  • php多进程中的阻塞与非阻塞操作实例分析

    本文实例讲述了php多进程中的阻塞与非阻塞操作.分享给大家供大家参考,具体如下: 我们通过pcntl_fork来创建子进程,使用pcntl_wait和pcntl_waitpid来回收子进程. 子进程退出后,父进程没有及时回收,就会产生僵尸进程. 例1: <?php define('FORK_NUMS', 5); $pids = array(); //我们创建5个子进程 for($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); i

随机推荐