lua协程并发下载简单测试 lua协程原理

   2023-02-09 学习力0
核心提示:下载8个1m大小文件,测试五次分别耗时12.038s,10.316s,8.955s,11.275s,9.499s(lua代码实现如下)require "socket"--host = "www.w3.org"--file = "/TR/REC-html32.html"function lua_string_split(str, split_char)--字符串拆分local sub_str_tab = {};w

下载8个1m大小文件,测试五次分别耗时12.038s,10.316s,8.955s,11.275s,9.499s(lua代码实现如下)

require "socket"

--host = "www.w3.org"
--file = "/TR/REC-html32.html"

function lua_string_split(str, split_char)    --字符串拆分

    local sub_str_tab = {};
    while (true and str ~= nil) do
        local pos = string.find(str, split_char);
        if (not pos) then
            sub_str_tab[#sub_str_tab + 1] = str;
            break;
        end
        local sub_str = string.sub(str, 1, pos - 1);
        sub_str_tab[#sub_str_tab + 1] = sub_str;
        str = string.sub(str, pos + 1, #str);
    end

    return sub_str_tab;
end


function download(url)
    local infolist = lua_string_split(url,"/")
    local cache_file = infolist[#infolist]

    local host = infolist[3]
    local pos = string.find(url, host)
    local file = nil
    if pos then
        file = string.sub(url, pos + #host)
    end
    pos = nil

    local out = io.open(cache_file,"wb")
    local c = assert(socket.connect(host, 80))
    local count = 0
    local pos = nil

    c:send("GET " ..file .." HTTP/1.0\r\n\r\n")
    while true do
        local s, status, partial = receive(c)
        count = count + #(s or partial)
        local data = s or partial

        if data then
            if pos == nil then            --去除响应头
                pos = string.find(data, "\r\n\r\n")
                if pos then
                    out:write(string.sub(data, pos + #"\r\n\r\n"))
                end
            else
                out:write(data)
            end
        end
        if status == "closed" then break end
    end
    c:close()
--  print(file, count)
    out:close()
--    os.execute("del " .. cache_file)
end

function receive(connection)
    connection:settimeout(0)
    local s, status, partial = connection:receive(2^10*100)
    if status == 'timeout' then
        coroutine.yield(connection)
    end
    return s or partial, status
end

threads = {}

function get(url)
    local co = coroutine.create(function ()
        download(url)
    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
            connections[#connections + 1] = res
            if #connections == #threads then
                local a, b, err = socket.select(connections)
                for k, v in pairs(a) do
                    --print(k, 'a=a', v)
                end
                for k, v in pairs(b) do
                    --print(k, 'b=b', v)
                end
            end
        end
    end
end

--get("http://www.w3.org/TR/REC-html32.html")
--get("http:///1/将夜") --下载中文会出错


local files = {'a','b','c','d','e','f','g','h'}
for i=1,#files do
    get("http://127.0.0.1/" .. files[i] .. ".file")
end

dispatch()

print(os.clock())

下载8个1m大小文件,测试五次分别耗时12.324s,14.407s,13.883s,15.188s,8.887s(python代码实现如下)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
import time
import urllib
import urllib2
import multiprocessing
from time import clock

def worker(pline):

        rinfo = pline.split("/")
        filename, url = rinfo[len(rinfo)-1], pline

        filename = urllib2.unquote(filename)
        try:
                f = urllib2.urlopen(url,timeout=10800)
                with open(filename, "wb") as code:
                        code.write(f.read())
        except:
                print sys.exc_info()
                return 0

        return 1
#
# main
#

if __name__ == "__main__":

        start = clock()
        pool_size = multiprocessing.cpu_count() * 2
        pool = multiprocessing.Pool(processes=pool_size)

        for i in ["a","b","c","d","e","f","g","h"]:
                url = "http://127.0.0.1/"+i+".file"
                pool.apply_async(worker, (url,))
                
        pool.close()
        pool.join()
        end = clock()
        print (end-start)

就算把python的进程池设置为1个,利用单cpu跑,耗时结果测试也是一样的。看不出来lua的协程对性能有多大的提升,感觉用多进程能实现的,就还是不要去折腾协程吧,毕竟协程不能利用多核的优势,编程也麻烦很多。

附:lua使用luasocket库发起http请求很方便

local http = require("socket.http")

local chunkbody = {}
res, code, headers = http.request {
        method = "GET",
        url = "http://127.0.0.1/get.php",
        sink = ltn12.sink.table(chunkbody)
}

if res ~= nil then
        print(code)
        for k,v in pairs(headers) do
                print(k .. ":" .. v)
        end
        print(table.concat(chunkbody))
else
        io.write(code .. "\n")
end

--res, code, headers = http.request("http://127.0.0.1/post","name=admin&passwd=adminpwd")
local postdata = "name=admin&passwd=adminpwd"
chunkbody = {}
res, code, headers = http.request {
        method = "POST",
        url = "http://127.0.0.1/post",
        headers = {
                ["Content-Type"] = "application/x-www-form-urlencoded",
                ["Content-Length"] = string.len(postdata)
        },
        source = ltn12.source.string(postdata),
        sink = ltn12.sink.table(chunkbody)
}
if res ~= nil then
        print(code)
        for k,v in pairs(headers) do
                print(k .. ":" .. v)
        end
        print(table.concat(chunkbody))
else
        io.write(code .. "\n")
end

--[[
200
connection:close
content-type:text/html
date:Sun, 16 Nov 2014 16:02:16 GMT
transfer-encoding:chunked
x-powered-by:PHP/5.3.3
server:openresty/1.7.2.1
a and b
201
connection:close
content-type:application/octet-stream
date:Sun, 16 Nov 2014 16:02:16 GMT
transfer-encoding:chunked
server:openresty/1.7.2.1
pass
--]]
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • LUA解析json小demo
    需要修改的json数据gui-config.json{"configs": [{"server": "JP3.ISS.TF","server_port": 443,"password": "58603228","method": "aes-256-cfb","remarks": ""},{"serv
    03-16
  • 第二十三篇:在SOUI中使用LUA脚本开发界面
    像写网页一样做客户端界面可能是很多客户端开发的理想。做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑。当需求变化时,只需要在服务端把相关代码调整一下,用户即可看到新的
    03-16
  • windows下编译lua源码"><转>windows下编译lua源
    因为之前一直使用 lua for windows 来搭建lua的使用环境,但是最新的 lua for windows 还没有lua5.2,我又想用这个版本的lua,所以被逼无奈只能自己编一下lua源码。首先从 lua的官网 下载你想要使用的lua源码,比如我下载的就是lua5.2。解压后内容如下:
    03-16
  • lua:使用Lua处理游戏数据
    在之前lua学习:lua作配置文件里,我们学会了用lua作配置文件。其实lua在游戏开发中可以作为一个强大的保存、载入游戏数据的工具。 比如说,现在我有一份表单:data.xls用什么工具解析这个Excel文件并将数据载入游戏?我们可以使用Lua来完成这个工作。不过要
    03-16
  • 第1课 - 学习 Lua 的意义
    第1课 - 学习 Lua 的意义
    第1课 - 学习 Lua 的意义1.Lua 简介           (1) 1993年、巴西(2) 小巧精致的脚本语言,大小只有 200K(3) 用标准C语言写成,能够在所有的平台上编译运行(4) 发明的目标是嵌入在C/C++中,为应用程序提供灵活的扩展和定制功能(5) 不适合用于开发
    03-16
  • RedisTemplate 常用API+事务+陷阱+序列化+pipeline+LUA
    RedisTemplate 常用API+事务+陷阱+序列化+pipel
    https://www.jianshu.com/p/7bf5dc61ca06/https://blog.csdn.net/qq_34021712/article/details/79606551https://www.jianshu.com/p/c9f5718e58f0dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/depe
    03-08
  • Nginx动态路由的新姿势:使用Go取代lua nginx路由规则
    Nginx动态路由的新姿势:使用Go取代lua nginx路
    导语: 在Nitro 中, 我们需要一款专业的负载均衡器。 经过一番研究之后,Mihai Todor和我使用Go构建了基于Nginx、Redis 协议的路由器解决方案,其中nginx负责所有繁重工作,路由器本身并不承载流量。 这个解决方案过去一年在生产环境中运行顺畅。 以下是我
    03-08
  • cocos2d-lua 控制台输入Lua指令方便调试
    用脚本进行开发,如果不能实时去输入指令,就丧失了脚本的一大特色,所以对cocos2d-x程序稍微修改下,使其可以直接从控制台读入lua指令,方便调试。1 首先在行首加入lua的引用,如下1 #include "main.h"2 #include "AppDelegate.h"3 #include "cocos2d.h"4 #i
    02-09
  • lua_touserdata
    void *lua_touserdata(lua_State*L,intindex);如果给定索引处的值是一个完整的userdata,函数返回内存块的地址。如果值是一个lightuserdata,那么就返回它表示的指针。否则,返回NULL。例如: 在CCLuaStack::executeFunction()函数中有一段代码是用来获取c++
    02-09
  • Lua 5.2 中文参考手册
    闲来无事,发现Lua更新到了5.2.2,参考手册也更到了5.2,在网上发现只有云风翻译的5.1版,花了几天时间翻译了一些。参考手册有点长,又要随时修改,所以在github上建了项目,有需要的朋友可以看看,同时也欢迎指正。中文手册:Lua 5.2中文参考手册
    02-09
点击排行