lua中协程的创建和使用

  • Post author:
  • Post category:其他



协程

协程:协程有三个状态,挂起、运行,死亡

协程与多线程情况下得线程比较类似,有自己的堆栈,自己的局部变量,有自己的指针指令,但与其他协同程序共享全局变量等很多信息。线程和协程的主要不同在于:在多处理器情况下,从概念上来讲多线程程序同时可以运行多个线程,而协程是通过协作来完成,在任意指定时刻只有一个协程在运行,并且这个正在运行的协程只有在必要时才会被挂起

协程、线程和进程的区别

进程是资源分配的最小单位,而线程是程序执行的最小单位,这句话其实并不是完全正确,因为还有比线程还轻量级的存在,那就是协程

进程:进程简单来说就是一个正在运行的程序,它是资源分配的最小单位,是由内核控制的,进程间的切换消耗的资源是比较大的,需要保存上下文信息,读取上下文信息,还有用户态到内核态在到用户态的切换消耗

线程:线程是比进程轻量级的存在,一个进程可以拥有多个线程,而且多个线程可以同时执行;一个进程的奔溃在现场保护的作用下不会影响到其他进程,但是一个线程的奔溃会导致整个进程的奔溃,所以说多进程比多线程健壮,线程也是由内核来管理的,所以说在线程间切换也会涉及到从用户态到内核态在到用户态的切换,还有上下文信息的保存和读取,消耗是比较大的;除此之外多线程间的同步一般情况下是使用锁,加锁和解锁的消耗也是很大的

协程:协程是比线程还轻量级的存在,一个进程可以有多个线程,一个线程可以有多个协程;但协程和线程的区别是多个协程之间不能同时运行,同一时间只能有一个协程在执行;协程的相比于线程的优点是协程不是由内核管理的,它是由用户自己管理的,所以说在多个协程之间切换的消耗是大大的小于线程间切换和进程间切换的消耗的,而且它的同步也不需要加锁,自己就能实现同步,消耗是进程线程协程这三个里面最小的

协程的几个常用方法

coroutine.create() 创建并返回协程,参数时一个函数,和resume配合使用时就会唤醒函数调用

coroutine.resume(co, val1, …)  重启协程,配合create一起使用

coroutine.yield() 挂起协程,经协程设置为挂起状态,和resume配合使用

coroutine.status() 查看协程的三种状态

coroutine.wrap() 创建协程,返回一个函数,一旦调用这个函数,就进入corotine和creat功能重复

coroutine.running()返回正在跑的coroutine,当调用running的时候,就是返回也coroting得线程号

协程简单的使用

创建和唤醒函数的使用

co = coroutine.create(
    function (i)
        print(i)
    end
)

--使用resume将这个协程唤醒
coroutine.resume(co,2)        --输出 2
--唤醒执行完之后,协程进入死亡状体
print(coroutine.status(co))   --输出dead

创建、唤醒,挂起,查看状态函数的使用

--创建一个协程
co1 = coroutine.create(
    function ()
        for i = 1, 10, 1 do
            print(i)
            if i == 3 then
                --查看当前得状态,此时正在运行中
                print(coroutine.status(co1))      --输出running
                print(coroutine.running())     --输出  thread:xxxxxx
            end
            --挂起当前协程,在挂起之后需要重新唤醒当前协程
            coroutine.yield()
        end
    end
)

coroutine.resume(co1)
coroutine.resume(co1)
coroutine.resume(co1)
print(coroutine.status(co1))   --输出是挂起状态

创建协程并返回一个函数

--创建一个协程,并返回一个函数
co2 = coroutine.wrap(
    function ()
        for i = 1, 10, 2 do
            print(string.format("%d = %d",i,i))
        end
    end
)
print(coroutine.running())
co2()

具体案例

function foo(a)
    print("foo 函数输出:",a)
    return coroutine.yield(2 * a)
end

co3 = coroutine.create(function (a,b)
    print("第一次协程执行输出:",a,b)
    local r = foo(a + 1)

    print("第二次协程执行输出:",r)
    local r,s = coroutine.yield(a + b,a - b)

    print("第三次协程执行输出:",r,s)
    return b, "结束协程"
end
)

print(coroutine.resume(co3,10,1))
print(coroutine.resume(co3,"w"))
print(coroutine.resume(co3,"s","q"))

消费者和生产者模型

local newProductor
function productor()
    local i = 0
    while true do
        i = i + 1
        send(i)
    end
end

function consumer()
    while true do
        local i = receive()
        print(i)
    end
end

function receive()
    local status,value = coroutine.resume(newProductor)
    return value
end

function send(x)
    coroutine.yield(x)
end

newProductor = coroutine.create(productor)
consumer()



版权声明:本文为choudan8888原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。