初识lua协同程序

2023-12-25 12:32
文章标签 初识 lua 协同程序

本文主要是介绍初识lua协同程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

协程类似与线程,但与线程不同,线程可以多个线程同时运行,但是协程需要彼此协作的运行,一个具有多个协程的程序任意时刻只能运行一个协程,并且在运行协程只会在其显示地要求挂起时,才会暂停。

一个协程有4种不同的状态:挂起,运行,死亡和正常。创建一个协程时,他处于挂起状态。

coroutine.status(co)检查协程的状态

coroutine.resume(co)用于启动或再次启动一个协程的执行,将其由挂起改为运行。

coroutine.yield()用于将一个运行中的协同程序挂起,而且之后可以用resume再运行

当一个协程A唤醒另一个协程B时,协程A即不是挂起状态,也不是运行状态,此时处于正常状态。

lua的协程可以通过一对resume yield来交换数据。

co = coroutine.create(function(alb,c)

        print("co",alb,c) 

        end )

coroutine.resume(co,1,2,3)--->co 1 2 3

co = coroutine.create(function(a,b)

        coroutine.yield(a+b,a-b) 

        end )

print(coroutine.resume(co,20,10)) ---->true 30 10

lua提供的是非对称的协同程序,用两个函数来控制协同程序的执行。

1 协程可以用来实现迭代器

常规实现:

function P(a,n)

n = n or #a

if n <= 1 then

    printResult(a)

else

    for i  =1 , n do

    a[n],a[i] = a[i],a[n]

    P(a,n-1)

    a[n],a[i]=a[i],a[n]

    end

end

end

协程实现

function permutations(a)

    return coroutine.wrap(function() P(a) end)

end

function P(a,n)

n = n or #a

if n<= 1 then

    coroutine.yield(a)

else

    for i  =1 , n do

        a[n],a[i] = a[i],a[n]

        P(a,n-1)

        a[n],a[i]=a[i],a[n]

    end

end

end

coroutine.wrap创建一个新的协程,不同于create,wrap并不返回协程本身,而是返回一个函数。

2 协程实现下载

协程是非抢占式的,因此当有一个线程被阻塞了,其他的线程都会被阻塞,这是不可以接受的。

下载的时候,如果同时下载多个文件,为每个下载任务创建一个新的线程,只要一个线程无可用数据,就可以将控制权转让给一个简单的调度程序,这个调度程序会去调度其他的下载程序。

function download(host ,file)

    local c = assert(socket.connect(host,80))

    local count = 0

    c:send("GET"..file.."HTTP/1.0/r/n")

    while true do

        local s , status , partial = receive(c)

        count = count + #(s or partial)

        if status == "closed" then break end

    end

    c:close()

    print(file , count)

    end

function receive (connection)

    connection:settimeout(0)

    local s , status , partial = connection:receive(2^10)

    if status == "timeout" then

         coroutine.yield(connection)   

     end

    return s or partial , status

end

threads = {}

function get (host , file)

    local co = coroutine.create( function ()

        download(host , file)

     end)

    table.insert(threads, co)

end

function dispatch()

    local i = 1

    local connections = {}

    while true do

        if threads[i] == nil then

            if threads[1] == nil then break end

            i = 1

            connections = {}

         end

        local status , res = coroutine.resume(threads[i])

        if not res then

            table.remove(threads,i)

        else

            i = i + 1

            if #connection == #threads then

                socket.select(connections) --->将所有超时的连接收集到一个connections的table中,receive会将超时的连接通过yield传递,如果所有的连接都超时,调度程序就调用select来等待这些连接的状态发生变化。

            end

         end

    end

end









这篇关于初识lua协同程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/535513

相关文章

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

由Lua 粘合的Nginx生态环境

转自:http://blog-zq-org.qiniucdn.com/pyblosxom/oss/openresty-intro-2012-03-06-01-13.html -- agentzh tech-club.org 演讲听录 免责聲明 Lua 粘合的 Nginx 生态环境 2.1. openresty 2.2. 配置小语言 2.3. ngx_drizzle 2.4.

Debugging Lua Project created in Cocos Code IDE creates “Waiting for debugger to connect” in Win-7

转自 I Installed Cocos Code IDE and created a new Lua Project. When Debugging the Project(F11) the game window pops up and gives me the message waiting for debugger to connect and then freezes. Also a

docker学习系列(一)初识docker

在第一版本上线之后公司,我们决定将之前使用的开源api文档项目转移到本公司的服务器之上,之前用的是showdoc,showdoc利用的是php技术,作为java程序员表示需要快速部署php环境以及apach容器都需要时间,所以采用第二种方法,即利用docker进行快速部署(虽然学习成本也不比php少)。 一、docker简介 docker的官网是https://www.docker.com,

框架template初识

框架初识 框架就是一个别人帮我们搭好的舞台,造好了很多现成的工具供我们使用,让开发过程更快速、简洁。 Gin框架介绍 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 Gin是一个用Go语言编写的web框架。它是一个类似于martini 但拥有更好性能的API框架, 由于使用了 httprouter,速度提高了近40倍。 第一个Gin示例 package mai

Docker+FastDFS+Lua搭建文件服务器进阶版

使用FastDFS+Nginx+Lua+GraphicsMagick搭建类似淘宝的图片服务器 1、FastDFS安装1.1、镜像下载1.2、开启tracker容器1.3、开启storage容器1.4、测试 2、FastDFS集成Nginx+lua+GraphicsMagick2.1、依赖包下载2.2、安装软件基础包2.3、依赖安装2.4、配置Lua脚本实现图片缩略图2.5、修改nginx.c

【数据结构】--初识泛型

1. 包装类 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 除了 Integer 和 Character, 其余基本类型的包装类都是首字母大写。 1.2 (自动)装箱和(自动)拆箱 装箱(装包): 把 基本数据类型 变为 包装类类型 的过程 叫做装箱。 反汇编指

初识Linux · 进度条

目录 前言: 1 缓冲区和回车换行 2 进度条 前言: 我们目前学习了些许知识,已经足够支持我们写一个非常非常小的项目了,即进度条,相信大家都有过下载游戏,等待游戏更新完成的时候,那么此时就有一个进度条,代表着游戏的更新进度,那么我们今天就来模拟实现这个过程,在此之前,我们需要一些预备知识。 1 缓冲区和回车换行 回车换行?是的,你没有看错,相信不少人对换行有一定的误解,我们