2012-11-11 9 views
5

मैं एक बड़ी फाइल डाउनलोड करना चाहता हूं और साथ ही अन्य चीजों को संभालना चाहता हूं।मैं लुआ पुस्तकालयों से कैसे निपटूं जो coroutine.yield() नहीं है?

हालांकि, luasocket.http कभी नहीं coroutine.yield() कहता है। फ़ाइल डाउनलोड करते समय बाकी सब कुछ जम जाता है।

यहाँ एक उदाहराणदर्शक उदाहरण है, जिसमें मैं एक साथ एक फ़ाइल डाउनलोड करने और कुछ संख्या मुद्रित करने के लिए प्रयास करें:

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!' 

चल रहा है यह इस का उत्पादन:

1 
Downloading large file 
FINISHED download (200, 5242880bytes) 
2 
3 
4 
5 
6 
7 
8 
9 
10 
FINISHED printing numbers 
Both done! 

आप देख सकते हैं, printRoutineresume है डी पहले। यह नंबर 1 और yield एस प्रिंट करता है। downloadRoutine तो resume घ, जो पूरी फ़ाइल डाउनलोड, उपज के बिना है। केवल तभी शेष संख्या मुद्रित हैं।

मैं अपने खुद के सॉकेट पुस्तकालय लिखने के लिए नहीं चाहता! मैं क्या कर सकता हूँ?

संपादित करें (बाद में उसी दिन): कुछ MUSH उपयोगकर्ता have also noticed। वे सहायक विचार प्रदान करते हैं।

+1

कोरआउट्स धागे नहीं हैं। आपको धागे की तरह उनका इलाज नहीं करना चाहिए। यदि कोई प्रक्रिया उपज नहीं करना चाहती है, तो यह नहीं जा रहा है, न ही आप इसे उपज के लिए मजबूर कर सकते हैं। लुआसॉकेट में गैर-अवरुद्ध आईओ के लिए कुछ सुविधाएं हैं, लेकिन मैं लुआसॉकेट से बहुत परिचित नहीं हूं, इसलिए आपको उनकी जांच करनी होगी। –

+1

लुआसॉकेट एसिंक्रोनस (यानी गैर-अवरुद्ध) संचालन का समर्थन करता है। लाइब्रेरी को फिर से लिखने से पहले आरटीएफएम। – Mud

+3

मिड: हाँ, कच्चे 'सॉकेट 'करता है। लेकिन 'socket.http' नहीं है। (देखें http://www.mail-archive.com/[email protected]/msg04969.html।) – Anko

उत्तर

5

मुझे नहीं लगता कि आप PiL advice या copas library का उपयोग क्यों नहीं कर सकते (यह लगभग उसी उत्तर है जैसा here दिया गया है)।

Copas सॉकेट इंटरफ़ेस (नहीं socket.http) लपेटता है, लेकिन आप निम्न स्तर इंटरफ़ेस का उपयोग क्या आप कुछ इस तरह (परीक्षण नहीं) होनी चाहिए पाने के लिए कर सकते हैं:

require("socket") 
local conn = socket.tcp() 
conn:connect("ipv4.download.thinkbroadband.com", 80) 
conn:send("GET /5MB.zip HTTP/1.1\n\n") 
local file, err = conn:receive() 
print(err or file) 
conn:close() 

फिर आप को copas से addthread उपयोग कर सकते हैं आपको एक गैर-अवरुद्ध सॉकेट दें और फ़ंक्शन receive करने के लिए उपयोग करें जबकि कुछ प्राप्त करने के लिए है। जबकि settimeout(0) का उपयोग करके सीधे आपको अधिक नियंत्रण देता है

copas का उपयोग करना, कम काम है।

+0

सहायक विकल्प के लिए धन्यवाद! यह मेरी विशिष्ट समस्या हल करता है। मेरा * प्रश्न * अधिक सामान्य है हालांकि: कई अन्य पुस्तकालय, जैसे लुआसेक के 'एसएसएलएचटीपीएस' (पुन: कार्यान्वित करने के लिए गैर-तुच्छ) अभी भी तुल्यकालिक हैं ... – Anko

+0

अच्छा बिंदु, हालांकि आप अभी भी ऐसा करने में सक्षम हो सकते हैं ssl.https के साथ बात।असल में, मैंने जो उदाहरण दिया है वह एसएसएलएचटीपीएस (http://notebook.kulchenko.com/programming/https-ssl-calls-with-lua-and-luasec) के साथ मेरे उदाहरण का सरलीकृत संस्करण है। ऐसा कहकर, मुझे यकीन नहीं है कि 'ssl.https' settimeout (0) के साथ समान तरीके से काम करता है क्योंकि मुझे इसका परीक्षण करने का मौका नहीं मिला है। –

2

Coroutines धागे नहीं हैं; वे सहकारी हैं, एक साथ नहीं। जब एक कोरआउटिन दूसरे से/से उत्पन्न होता है, तो यह अवरुद्ध हो जाता है। आपके पास वेनिला लुआ में दो एक साथ निष्पादन पॉइंटर्स नहीं हो सकते हैं।

हालांकि, अगर आप उस प्रभाव के लिए बाहरी पुस्तकालयों का उपयोग कर सकते हैं। सबसे लोकप्रिय लोगों में से एक Lua Lanes है।

+0

अधिकतर उपज करने के लिए 'socket.http' को फिर से लिखना तुलना में आसान लगता है। लेकिन पुस्तकालय कोड को अवरुद्ध करने के एक बड़े टुकड़े के आसपास काम करने के लिए, यह एक महान हैक होगा! – Anko

संबंधित मुद्दे