-
协程Coroutine——用同步的方式编写异步的逻辑
2015-10-01 16:29:59协程Coroutine——用同步的方式编写异步的逻辑摘要:Lua中的协程是用户级线程,任何时候只有一个协程在真正运行,程序员能够控制协程的切换和运行,可以用同步的方式编写异步的逻辑。 进程、线程、协程在操作系统中...摘要:Lua中的协程是用户级线程,任何时候只有一个协程在真正运行,程序员能够控制协程的切换和运行,可以用同步的方式编写异步的逻辑。
进程、线程、协程
在操作系统中,进程拥有自己独立的内存空间,多个进程同时运行不会相互干扰,但是进程之间的通信比较麻烦;线程拥有独立的栈但共享内存,因此数据共享比较容易,但是多线程中需要利用加锁来进行访问控制:这是个非常头痛的问题,不加锁非常容易导致数据的错误,加锁容易出现死锁。多线程在多个核上同时运行,程序员根本无法控制程序具体的运行过程,难以调试。而且线程的切换经常需要深入到内核,因此线程的切换代价还是比较大的。
协程coroutine拥有自己的栈和局部变量,相互之间共享全局变量。任何时候只有一个协程在真正运行,程序员能够控制协程的切换和运行,因此协程的程序相比多线程编程来说轻松很多。由于协程是用户级线程,因为协程的切换代价很小。
协程的挂起
程序员能够控制协程的切换,这句话需要认真理解下。程序员通过yield让协程在空闲(比如等待io,网络数据未到达)时放弃执行权,通过resume调度协程运行。协程一旦开始运行就不会结束,直到遇到yield交出执行权。Yield和resume这一对控制可以比较方便地实现程序之间的“等待”需求,即“异步逻辑”。总结起来,就是协程可以比较方便地实现用同步的方式编写异步的逻辑。
“生产者-消费者”
异步逻辑最常见的例子便是“生产者-消费者”案例,消费者consumer需要等待生产者producer,只有生产了数据才能消费,这便是一个“等待的异步需求”。
Lua中协程常用接口:
coroutine接口 说明: coroutine.create(func) 创建一个协程 coroutine.resume(coroutine, [arg1, arg2..]) 执行协程,第一次从头开始运行,之后每次从上次yield处开始运行,每次运行到遇到yield或者协程结束 coroutine.yield(…) 挂起当前协程,交出执行权 利用协程的yield和resume实现的生产者-消费者代码:
--生产者 function producer() return coroutine.create( function() while true do local a = io.read() --挂起协程,交出执行权 coroutine.yield(a) end end ) end --消费者 function consumer(pro) while true do --执行生产者协程 local s, v = coroutine.resume(pro) print ('s='..tostring(s)..', v='..v) end end p = producer() consumer(p)
coroutine实现server
接下来再看一个用协程处理客户端请求的服务器:server主线程接收client请求,接受连接上来后为每个client创建一个coroutine,这个coroutine监听client发来的数据如果有数据发来那么进行处理,如果没有数据那么yield挂起交出执行权。
-- server.lua --listen connection from client, and make a coroutine for each connection --each coroutine recv data from client and send data back to client local socket = require("socket") local host = "127.0.0.1" local port = "8888" local connections = {} local threads = {} function receive_data(sock_id) local conn = connections[sock_id] if conn ~= nil then local recvt, t, status = socket.select({conn}, nil, 1) if #recvt > 0 then local receive, receive_status = conn:receive() if receive_status ~= "closed" then if receive then assert(conn:send(receive .. "\n")) print("Receive Client " .. sock_id.. " : " ..receive) end --disconnect else print("Client " .. sock_id .. " disconnect!") connections[sock_id].close() connections[sock_id] = nil threads[sock_id] = nil end end --yield, stop execution of this coroutine coroutine.yield() end end --handle data from client: send data back to client function connection_handler(sock_id) while true do --print ('connection_handler.. id=' .. sock_id) local conn = connections[sock_id] if conn == nil then break end local data, status = receive_data(sock_id) end end --create coroutine to handle data from client function create_handler(sock_id) --print 'create_handler..' local handler = coroutine.create(function () connection_handler(sock_id) end) return handler end function accept_connection(sock_id, conn) print("accepted new socket ,id = " .. sock_id) connections[sock_id] = conn threads[sock_id] = create_handler(sock_id) end --schedule all clients function dispatch() for _sock_id, _thread in ipairs(threads) do --print ('dispatch, _sock_id = '.. _sock_id) coroutine.resume(threads[_sock_id]) end end function start_server() local server = assert(socket.bind(host, port, 1024)) print("Server Start " .. host .. ":" .. port) server:settimeout(0) local conn_count = 0 while true do --accept new connection local conn = server:accept() if conn then conn_count = conn_count + 1 accept_connection(conn_count, conn) end --deal data from connection dispatch() end end function main() start_server() end main() --client.lua -- send user input data to server and print data from server local socket = require("socket") local host = "127.0.0.1" local port = 8888 local sock = assert(socket.connect(host, port)) sock:settimeout(0) function main() print("Press enter after input something:") local input, recvt, sendt, status while true do input = io.read() if #input > 0 then assert(sock:send(input .. "\n")) end recvt, sendt, status = socket.select({sock}, nil, 1) while #recvt > 0 do local response, receive_status = sock:receive() if receive_status ~= "closed" then if response then print ('recv from server:'..response) recvt, sendt, status = socket.select({sock}, nil, 1) end else break end end end end main()
coroutine_server 运行
首先启动server,然后启动两个client去连接并进行输入,server利用coroutine对client的输入进行了回写,执行情况如下图所示:
github源码
https://github.com/harryzeng/coroutine_server
参考
http://my.oschina.net/wangxuanyihaha/blog/186401
http://www.kuqin.com/system-analysis/20110910/264592.html -
ajax中的async属性值之同步和异步及同步和异步区别
2020-10-23 10:27:52在Jquery中ajax方法中async用于控制同步和异步,当async值为true时是异步请求,当async值为fase时是同步请求。ajax中async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。 -
在控制器控制方式中,异步控制与联合控制有什么区别?
2020-04-20 15:42:06同步控制是指任何一条指令或指令中任何一个微操作的执行都是事先确定的,并且都受同一基准时标的...联合控制是同步控制和异步控制相结合的方式,即大多数操作(如CPU内部各操作)在同步时序信号的控制下进行,少数时...同步控制是指任何一条指令或指令中任何一个微操作的执行都是事先确定的,并且都受同一基准时标的时序信号所控制的方式。
异步控制无基准时标信号,微操作的时序是由专门的应答线路控制,即控制单元发出执行某一微操作的控制信号后,等待执行部件完成了该操作后发回“回答”或“结束”信号,再开始新的微操作。
联合控制是同步控制和异步控制相结合的方式,即大多数操作(如CPU内部各操作)在同步时序信号的控制下进行,少数时间难以确定的微操作(如涉及I/O操作)采用异步控制。 -
stm32 led屏控制卡_技术丨LED显示屏控制系统同步和异步的区别
2020-12-05 08:43:09它主要分为同步系统和异步系统,下面就这两种控制系统做一个对比分析:一、LED显示屏同步控制系统主要用来实时显示视频、图文、通知等。主要用于室内或户外全彩大屏幕显示屏。LED显示屏同步控制系统控制显示屏的工作...LED显示屏控制系统是组成LED屏的核心部件,主要负责接收来自计算机串行口或DVI接口的画面及视频信息,置入帧存储器,从而显示内容。它主要分为同步系统和异步系统,下面就这两种控制系统做一个对比分析:
一、LED显示屏同步控制系统
主要用来实时显示视频、图文、通知等。主要用于室内或户外全彩大屏幕显示屏。LED显示屏同步控制系统控制显示屏的工作方式基本等同于电脑的 监视器,它以至少60帧/秒更新速率点对应地实时映射电脑监视器上的图像,通常具有多灰度的颜色显示能力,可达到多媒体的宣传广告效果。
其特点是:实时性、表现力丰富、操作较为复杂、价格高,并且计算机显示器上的内容是完全同步显示,所以说,如果计算机关闭了,那么LED显示屏也就不显示,因此播放时间会受到一定限制。这种系统,主要是用于对实时性要求比较高的场所中。
二、LED显示屏异步控制系统
又称LED显示屏脱机控制系统或脱机卡。主要用来显示各种文字、符号和图形或动画为主。画面显示信息由计算机编辑,经RS232/485串行口预先置入LED屏的帧存储器,然后逐屏显示播放,循环往复,显示方式丰富多彩,变化多样。
其特点是:操作简单、价格低廉、使用范围较广。最大的特点是可以分区域控制显示屏幕内容,与计算机显示器上的内容是不同步的。先在计算机上编辑好以后,再发送到控制卡上,这时控制卡再进行显示。所以,即使计算机关闭了,LED显示屏也能够进行显示,但是播放信息量会受到一定限制,因为控制卡存储量有一定的范围。它适用于对实时性要求不高的场所中。
图|沛琦
文|沛琦
我在这里等你哟!
推荐阅读
Recommended reading
雷曼 -康硕展创意LED显示屏落户丘成桐国际会议中心技术丨LED电子显示屏核心技术——颜色处理技术资讯丨户外LED市场的发展趋势技术丨LED显示屏模组偏色解决方法 -
同步调制和异步调制区别
2019-05-08 17:36:58在PWM控制电路中,载波频率 fc 和调制信号频率 fr 之比成为载波比,根据载波信号和信号波信号是否同步分为同步调制和异步调制。 1 什么是异步调制? 载波信号和调制信号不保持同步的方式称为异步调制,如下图所示,...在PWM控制电路中,载波频率 fc 和调制信号频率 fr 之比成为载波比,根据载波信号和信号波信号是否同步分为同步调制和异步调制。
1 什么是异步调制?
载波信号和调制信号不保持同步的方式称为异步调制,如下图所示,异步调制的载波频率是不变的,但是调制波的频率是改变的。同时由载波比的定义可知,异步调制的载波比也是变化的;
异步调制还有一个重要的特点就是输出的脉冲波是不对成的,不仅1/4脉冲不对成,正负半周期的脉冲也不对称,这会导致电流输出的谐波较多。如下图所示:
2 什么是同步调制?
同步调制的载波比N等于常数,并在变频时使载波和调制波保持同步的方式称为同步调制。
其特点如下:
第一:载波比N为常数,每个周期内输出的脉冲数的固定。这是因为载波比固定,所以一个周期的调制波内的载波数目是一定的,从而一个周期内的脉冲个数也是固定的。
第二:脉冲相位固定。这是因为无论调制波的频率如何变化,载波个数不变。无论调制波的频率增大减小,反应到一个周期的过程中是没有变化的。
3 同步调制和异步调制区别总结
同步调制和异步调制在控制方式上其实是有很大区别的;
第一:实现方式不同。
异步调制只需要给定定频率的载波,调制波的频率也不需要特定控制,而同步调制则需要复杂的算法使得载波和调制波同频同相;举个例子,在双闭环的矢量控制系统中其实是默认为异步调制的,因为我们所用的大部分SVPWM模块的思路都是先通过计算空间矢量法得到调制波,然后再与三角载波比较得到所需要的PWM脉冲。但是想要在双闭环实现同步调制,就必须使得载波和调制波同步,在电机的速度上升过程中,调制波的频率是时刻改变,这个时候要随时都能实现载波和调制波的同频同相就需要复杂的控制算法,实现起来相对困难。
第二:谐波含量不同。
异步调制的谐波含量要远高于同步调制。但是由于我们默认认知的电机控制系统似乎很少涉及到谐波的处理,其实根本原因是这些不考虑谐波的电机系统都是基于很高载波比的情况。因为变频器输出的PWM波的谐波主要集中在开关频率整数倍附近。 也就是说,载波比越大,开关频率越高,谐波的频率越高。 而变频器的负载是电机,电机是感性负载,高频信号通过电感,电流谐波将被衰减,谐波频率越高,衰减幅度越大。正是由于高次谐波被电机的感性特性所抑制,所以这些谐波被近似忽略了。而同步调制,通过使得载波比为3的整数倍,消除了3及其3的倍数次的谐波;并且通过适合PWM波正负半周期对称(N载波比取奇数)消除偶次谐波,总体同步调制所含谐波只为6k±1次谐波(常见的5 7 11 13次谐波)等。
第三:应用场合的不同。
其实在小功率的电机控制系统中,所以就算使用的开关器件开关频率较高,开关损耗仍然较小,并不太需要取刻意的消除谐波。但是在大功率的场合,如果开关频率太高,就会导致开关损耗升高,使用异步调制的话会导致大量的高幅值的低次谐波,所以需要应用同步调制的策略来消除低频的谐波。
-
socket同步和异步通信区别_单片机串行通信基础:同步通信和异步通信
2020-12-01 19:14:06串行通信的分类按照串行数据的时钟控制方式,串行通信可分为同步通信和异步通信两类。1. 异步通信(Asynchronous Communication)在异步通信中,数据通常是以字符为单位组成字符帧传送的。字符帧由发送端一帧一帧地... -
同步和异步
2017-01-26 01:16:45所谓同步执行模式,是指语句在同步执行模式下,将始终保持对程序流的控制,直至 程序结束。如查询操作,客户机上的应用程序在向服务器发出查询操作的指令后,将 一直等待服务器将查询结果返回客户机端,然后才... -
同步和异步的分析
2019-05-21 16:23:00其中同步方式、异步方式主要是由客户端(client)控制的,具体如下: 1.1 同步(Sync) 所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。 根据这个定义,Java中所有... -
同步式IO和异步式IO
2015-01-27 18:20:51夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞。当IO操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种IO模式就是通常的... -
同步和异步的概念
2020-10-19 23:13:47今天看到《WIN32多线程程序设计》的同步控制时,才发现原来自己对同步和异步的概念很模糊,甚至混淆。 下面都是高人们的见解,简单明了。 同步是指:当程序1调用程序2时,程序1停下不动,直到程序2完成回到程序1来... -
AJAX中同步和异步的区别和使用场景
2019-04-16 15:32:00在Jquery中ajax方法中async用于控制同步和异步,当async值为true时是异步请求,当async值为fase时是同步请求。ajax中async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。 jquery中... -
同步和异步的区别
2020-09-08 10:46:44目录同步概念优点使用场景异步概念优点使用场景两者比较 同步 概念 我们可以将同步看成是单线的执行,...4、同步流程是最天然的控制过程顺序执行的方式。 使用场景 比如银行的转账系统,对数据库的保存操作等等,都 -
ajax中同步和异步的区别
2017-02-06 09:09:20在Jquery中ajax方法中async用于控制同步和异步,当async值为true时是异步请求,当async值为fase时是同步请求。ajax中async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。 jquery中... -
同步串口和异步串口的区别及使用情况
2021-02-19 14:57:25而按照串行数据的时钟控制方式,串行通信又可分为同步通信和异步通信两种方式。 1、异步串行方式的特点 所谓异步通信,是指数据传送以字符为单位,字符与字符间的传送是完全异步的,位与位之间的传送基本上是... -
UART的同步通信和异步通信,通信方式,多机通信,流控
2018-11-09 15:02:01异步通信: 同步通信: 串行的单工,半双工,全双工: 串口的多机通信: UART的RTS, CTS: 一、流控,顾名思义就是流量控制的意思。目的是协调收发双方,使数据不会丢失。 二、很多人用... -
role-acl:使用操作,属性以及同步和异步条件的基于角色的访问控制-源码
2021-02-02 23:12:27许多 (基于角色的访问控制)实现方式不同,但是由于它模拟了现实中的角色(工作)分配,因此已广泛采用了基础知识。 但是,尽管数据变得越来越复杂; 您需要针对资源,主题甚至环境定义策略。 这称为 (基于属性的... -
【Ajax】-同步和异步
2018-09-30 21:24:03Jquery中ajax方法中async用于控制同步和异步,当async值为true时是异步请求,当async值为fase时是同步请求。ajax中async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。 概念解释: ... -
同步和异步的好处
2012-01-06 21:28:50同步处理和异步处理的好处比较: 同步的好处: 1、同步流程对结果处理通常更为简单,可以就近处理。 2、同步流程对结果的处理始终和前文保持在一个上下文内。 3、同步流程可以很容易捕获、处理异常。 4、... -
Promise-在Java中以同步的方式异步编程
2018-06-02 09:25:10Promise A+是commonJs规范提出的一种异步编程解决方案,比传统的解决方案—回调函数和事件—更合理和更强大。promise实现了Promise A+规范,包装了java中对多线程的操作,提供统一的接口,使得控制异步操作更加容易... -
异步操作(计算机程序执行分为同步执行和异步执行)
2020-04-06 17:42:20同步执行: 就是正常的计算机执行的三大顺序 顺序控制语句: 从上之下,从左至右 循环控制语句: if , switch 循环控制语句:for,while,do…while,for…in,forEach() 异步执行: 就是一种特殊的程序执行方式 定时器... -
基础补充(六)——同步调制和异步调制的区别
2019-06-24 20:08:26在PWM控制电路中,载波频率 fc 和调制信号频率 fr 之比成为载波比,根据载波信号和信号波信号是否同步分为同步调制和异步调制。 1 什么是异步调制? 载波信号和调制信号不保持同步的方式称为异步调制,如下图所示... -
同步与异步
2020-04-18 18:09:44(1)计算机程序执行分为同步执行和异步执行 (2)同步执行指的是正常的计算机程序执行的三大顺序流程,包括顺序控制语句、分支控制语句和循环控制语句 (3)异步执行是一种特殊的程序执行方式,包括定时器、延时器...