Ich möchte eine große Datei herunterladen und gleichzeitig andere Dinge behandeln.Wie gehe ich mit Lua-Bibliotheken um, die nicht coroutine.yield() enthalten?
Jedoch ruft luasocket.http
nie coroutine.yield()
. Alles andere friert beim Herunterladen der Datei ein.
Hier ist ein anschauliches Beispiel, in dem ich versuche, gleichzeitig eine Datei herunterzuladen und einige Zahlen drucken:
local http = require'socket.http'
local downloadRoutine = coroutine.create(function()
print 'Downloading large file'
-- Download an example file
local url = 'http://ipv4.download.thinkbroadband.com/5MB.zip'
local result, status = http.request(url)
print('FINISHED download ('..status..', '..#result..'bytes)')
end)
local printRoutine = coroutine.create(function()
-- Print some numbers
for i=1,10 do
print(i)
coroutine.yield()
end
print 'FINISHED printing numbers'
end)
repeat
local printActive = coroutine.resume(printRoutine)
local downloadActive = coroutine.resume(downloadRoutine)
until not downloadActive and not printActive
print 'Both done!'
Laufen sie dies erzeugt:
1
Downloading large file
FINISHED download (200, 5242880bytes)
2
3
4
5
6
7
8
9
10
FINISHED printing numbers
Both done!
Wie Sie sehen können, printRoutine
ist resume
d zuerst. Es druckt die Nummer 1 und yield
s. Die downloadRoutine
ist dann resume
d, die die gesamte Datei herunterlädt, ohne zu ergeben. Nur dann werden die restlichen Zahlen gedruckt.
Ich möchte nicht meine eigene Socket-Bibliothek schreiben! Was kann ich tun?
Bearbeiten (später am selben Tag): Einige MUSH-Benutzer have also noticed. Sie bieten hilfreiche Ideen.
Coroutines sind keine Threads. Sie sollten sie nicht wie Fäden behandeln. Wenn ein Prozess nicht nachgeben will, dann wird er es nicht tun, noch kann er es erzwingen. LuaSocket bietet einige Möglichkeiten für nicht blockierendes IO, aber ich kenne LuaSocket nicht sehr gut, daher müssen Sie sie untersuchen. –
LuaSocket unterstützt asynchrone (d. H. Nicht blockierende) Operationen. RTFM vor dem Umschreiben der Bibliothek. – Mud
Mud: Ja, die rohe "Socket" tut. Aber 'socket.http' nicht. (Siehe http://www.mail-archive.com/[email protected]/msg04969.html.) – Anko