2009-06-23 16 views
30

मैं यह पता लगाने नहीं कर सकते कि कैसे lua किसी भी आम समय चालें करने के लिए प्राप्त करने के लिए, इस तरह केकुछ सेकंड के लिए लुआ स्क्रिप्ट प्रतीक्षा/रोक/नींद/ब्लॉक बनाने का सबसे आसान तरीका?

  • नींद के रूप में - धागे पर सभी कार्रवाई रोक

  • रोकें/इंतजार - अगले पर मत जाओ आदेश है, लेकिन आवेदन में अन्य कोड जारी रखने के लिए

  • ब्लॉक की अनुमति देते हैं - मौजूदा जब तक अगले आदेश के लिए पर मत जाओ रिटर्न

और मैं पढ़ा है कि एक

while os.clock()<time_point do 
--nothing 
end 

CPU समय तक खाता है।

कोई सुझाव? क्या कोई एपीआई कॉल है जो मुझे याद आ रही है?

अद्यतन: मैं इस सवाल का एक लंबे समय पहले लिखा था वाह लुआ प्राप्त करने के लिए (एक समय पर कार्रवाई को फिर से चलाने की कोशिश कर रहा यानी खड़े हो जाओ, 1 सेकंड, नृत्य इंतजार, 2 सेकंड प्रतीक्षा करें, बैठने रुक जाता है के बिना, इन लगभग सभी होती हैं। एक ही तिमाही दूसरे में।) As it turned out WOW had purposely disabled pretty much everything that allows doing action on a clock because it could break the game or enable bots. मैं एक घड़ी फिर से बनाने के लिए लगा एक बार यह दूर ले जाया गया था, मैं की तरह एक काम सरणी (एक कार्रवाई और निष्पादन समय के साथ बनाने के पागल कुछ करना) और फिर रजिस्टर एक ईवेंट हैंडलर होगा सामान्य घटनाओं के समूह पर, जैसे माउस चाल, फिर भी हैंडलर में, किसी भी कार्रवाई की प्रक्रिया करें जिसका समय आ गया था। इवेंट हैंडलर वास्तव में हर एक्स मिलीसेकंड नहीं होता है, लेकिन अगर यह हर 2-100 एमएस हो रहा था, तो यह काफी करीब होगा। दुख की बात है कि मैंने कभी कोशिश नहीं की।

उत्तर

4

इससे इससे अधिक आसान नहीं होता है। नींद को आपके एफएलटीके या जो भी हो, में लागू किया जा सकता है, लेकिन यह मानक घटना इंटरप्ट के बिना मानक प्रकार की प्रणाली को सोने के सभी बेहतरीन तरीकों को शामिल करता है। देखें:

-- we "pcall" (try/catch) the "ex", which had better include os.sleep 
-- it may be a part of the standard library in future Lua versions (past 5.2) 
local ok,ex = pcall(require,"ex") 
if ok then 
    -- print("Ex") 
    -- we need a hack now too? ex.install(), you say? okay 
    pcall(ex.install) 
    -- let's try something else. why not? 
    if ex.sleep and not os.sleep then os.sleep = ex.sleep end 
end 

if not os.sleep then 
    -- we make os.sleep 
    -- first by trying ffi, which is part of LuaJIT, which lets us write C code 
    local ok,ffi = pcall(require,"ffi") 
    if ok then 
     -- print("FFI") 
     -- we can use FFI 
     -- let's just check one more time to make sure we still don't have os.sleep 
     if not os.sleep then 
     -- okay, here is our custom C sleep code: 
     ffi.cdef[[ 
      void Sleep(int ms); 
      int poll(struct pollfd *fds,unsigned long nfds,int timeout); 
     ]] 
     if ffi.os == "Windows" then 
      os.sleep = function(sec) 
       ffi.C.Sleep(sec*1000) 
      end 
     else 
      os.sleep = function(sec) 
       ffi.C.poll(nil,0,sec*1000) 
      end 
     end 
     end 
    else 
     -- if we can't use FFI, we try LuaSocket, which is just called "socket" 
     -- I'm 99.99999999% sure of that 
     local ok,socket = pcall(require,"socket") 
     -- ...but I'm not 100% sure of that 
     if not ok then local ok,socket = pcall(require,"luasocket") end 
     -- so if we're really using socket... 
     if ok then 
     -- print("Socket") 
     -- we might as well confirm there still is no os.sleep 
     if not os.sleep then 
      -- our custom socket.select to os.sleep code: 
      os.sleep = function(sec) 
       socket.select(nil,nil,sec) 
      end 
     end 
     else 
     -- now we're going to test "alien" 
     local ok,alien = pcall(require,"alien") 
     if ok then 
     -- print("Alien") 
     -- beam me up... 
      if not os.sleep then 
       -- if we still don't have os.sleep, that is 
       -- now, I don't know what the hell the following code does 
       if alien.platform == "windows" then 
        kernel32 = alien.load("kernel32.dll") 
        local slep = kernel32.Sleep 
        slep:types{ret="void",abi="stdcall","uint"} 
        os.sleep = function(sec) 
        slep(sec*1000) 
        end 
       else 
        local pol = alien.default.poll 
        pol:types('struct', 'unsigned long', 'int') 
        os.sleep = function(sec) 
        pol(nil,0,sec*1000) 
        end 
       end 
      end 
     elseif package.config:match("^\\") then 
      -- print("busywait") 
      -- if the computer is politically opposed to NIXon, we do the busywait 
      -- and shake it all about 
      os.sleep = function(sec) 
       local timr = os.time() 
       repeat until os.time() > timr + sec 
      end 
     else 
      -- print("NIX") 
      -- or we get NIXed 
      os.sleep = function(sec) 
       os.execute("sleep " .. sec) 
      end 
     end 
     end 
    end 
end 
1

आप   win.Sleep(milliseconds) मुझे मालूम होता है चाहता हूँ,।

हाँ, आप निश्चित रूप से नहीं एक व्यस्त-प्रतीक्षा की तरह आप का वर्णन करना चाहते हैं।

3

मैं नींद समारोह लपेटकर पर सी

2

मैं जॉन के साथ सहमत में मेजबान सिस्टम की नींद समारोह रैप करने के लिए एक सरल समारोह लागू करेगा। तुम भी lua में एक ठहराव समारोह (जो केवल तो अगर एक निश्चित शर्त हर बार बदल गया है देखने के लिए जाँच नींद होता है) को लागू करने के लिए इस लिपटे नींद समारोह इस्तेमाल कर सकते हैं। हुक का उपयोग करने का एक विकल्प है।

मैं बिल्कुल यकीन है कि आप अपने तीसरे bulletpoint साथ क्या मतलब है नहीं कर रहा हूँ (आज्ञा आमतौर पर नहीं पूरा अगले निष्पादित किया जाता है से पहले करते हैं?) लेकिन हुक भी इस के साथ मदद करने में सक्षम हो सकता है।

देखें: Question: How can I end a Lua thread cleanly? हुक का उपयोग करने के उदाहरण के लिए।

3

शुद्ध लूआ केवल एएनएसआई मानक सी में उपयोग करता है। लुइज़ फिगुरेडो के lposix module में आपको अधिक व्यवस्थित चीजों को करने की आवश्यकता है।

10

आप सीपीयू खाने के बिना शुद्ध लुआ में कर सकते हैं नहीं है, लेकिन वहाँ एक सरल, गैर पोर्टेबल तरीका है:

ओएस।निष्पादित ("नींद 1")

(यह अवरुद्ध कर देगा)

जाहिर है, ऑपरेटिंग सिस्टम पर काम करता है यह केवल जो "नींद 1" के लिए एक वैध आदेश, उदाहरण के यूनिक्स के लिए Windows है, लेकिन नहीं।

+0

ध्यान दें कि कुछ सिस्टम जहां यह काम करता है (उदा। ओएस एक्स) यह 'os.clock() 'अग्रिम नहीं करेगा, क्योंकि CPU समय का उपभोग नहीं किया जाता है। – Phrogz

20

[मैं John Cromartie's पोस्ट पर एक टिप्पणी के रूप में इस पोस्ट करने के लिए जा रहा था, लेकिन नहीं पता था एक टिप्पणी में स्वरूपण का उपयोग नहीं कर सकता है।]

मैं सहमत हूँ। Os.execute() के साथ इसे खोलने के लिए इसे निश्चित रूप से काम करना होगा, लेकिन सामान्य रूप से खोल कॉल करना महंगी है। कुछ सी कोड लपेटना रन-टाइम पर बहुत तेज़ होगा। C/C++ एक Linux सिस्टम पर है, तो आप इस्तेमाल कर सकते हैं:

static int lua_sleep(lua_State *L) 
{ 
    int m = static_cast<int> (luaL_checknumber(L,1)); 
    usleep(m * 1000); 
    // usleep takes microseconds. This converts the parameter to milliseconds. 
    // Change this as necessary. 
    // Alternatively, use 'sleep()' to treat the parameter as whole seconds. 
    return 0; 
} 

फिर, मुख्य में, कार्य करें:

lua_pushcfunction(L, lua_sleep); 
lua_setglobal(L, "sleep"); 

जहां "L" अपने lua_State है। फिर, C/C++ से कहा जाता है अपने लुआ स्क्रिप्ट में, आप अपने कार्यप्रणाली को कॉल करके उपयोग कर सकते हैं:

sleep(1000) -- Sleeps for one second 
3

दूसरा अनुरोध के लिए, रोकें/इंतजार है, जहां आप लुआ में प्रसंस्करण बंद करो और अपने आवेदन चलाने के लिए जारी है, तो आप coroutines की जरूरत है। आप नीचे दिए गए इस तरह की कुछ सी कोड के साथ अंत:

Lthread=lua_newthread(L); 
luaL_loadfile(Lthread, file); 
while ((status=lua_resume(Lthread, 0) == LUA_YIELD) { 
    /* do some C code here */ 
} 

और लुआ में, आपके पास निम्न:

function try_pause (func, param) 
    local rc=func(param) 
    while rc == false do 
    coroutine.yield() 
    rc=func(param) 
    end 
end 

function is_data_ready (data) 
    local rc=true 
    -- check if data is ready, update rc to false if not ready 
    return rc 
end 

try_pause(is_data_ready, data) 
1

यह भी एक libc/MSVCRT आवरण के रूप में विदेशी उपयोग करने के लिए आसान है:

> luarocks install alien 
lua से फिर

:

require 'alien' 

if alien.platform == "windows" then 
    -- untested!! 
    libc = alien.load("msvcrt.dll") 
else 
    libc = alien.default 
end 

usleep = libc.usleep 
usleep:types('int', 'uint') 

function sleep(ms) 
    while ms > 1000 do 
     usleep(1000) 
     ms = ms - 1000 
    end 
    usleep(1000 * ms) 
end 

print('hello') 
sleep(500) -- sleep 500 ms 
print('world') 

कैविट लेक्टर: मैंने एमएसविंडोज़ पर यह कोशिश नहीं की है; मुझे यह भी पता नहीं है कि msvcrt में नींद है()

18

यदि आप अपने प्रोजेक्ट में LuaSocket का उपयोग करते हैं, या बस इसे इंस्टॉल किया है और इसका उपयोग करने में कोई फर्क नहीं पड़ता है, तो आप socket.sleep(time) फ़ंक्शन का उपयोग कर सकते हैं जो सोता है एक निश्चित मात्रा (सेकंड में)।

यह विंडोज और यूनिक्स दोनों पर काम करता है, और आपको अतिरिक्त मॉड्यूल संकलित करने की आवश्यकता नहीं है।

मुझे यह जोड़ना चाहिए कि फ़ंक्शन पैरामीटर के रूप में आंशिक सेकंड का समर्थन करता है, यानी socket.sleep(0.5) आधा सेकेंड सो जाएगा। यह विंडोज़ पर Sleep() और nanosleep() अन्य जगहों का उपयोग करता है, इसलिए time बहुत कम हो जाने पर आपको विंडोज सटीकता के साथ समस्या हो सकती है।

8
खिड़कियों आप यह कर सकते हैं के लिए

:

os.execute("CHOICE /n /d:y /c:yn /t:5") 
7

नींद समारोह - उपयोग: sleep(1) -- sleeps for 1 second

local clock = os.clock 
function sleep(n) -- seconds 
    local t0 = clock() 
    while clock() - t0 <= n do 
    end 
end 

रोकें समारोह - उपयोग: pause() -- pause and waits for the Return key

function pause() 
    io.stdin:read'*l' 
end 

आशा है, यह वही है जो आपको चाहिए! : डी - जो DF

3
require 'alien' 

if alien.platform == "windows" then 
    kernel32 = alien.load("kernel32.dll") 
    sleep = kernel32.Sleep 
    sleep:types{ret="void",abi="stdcall","uint"} 
else 
    -- untested !!! 
    libc = alien.default 
    local usleep = libc.usleep 
    usleep:types('int', 'uint') 
    sleep = function(ms) 
    while ms > 1000 do 
     usleep(1000) 
     ms = ms - 1000 
    end 
    usleep(1000 * ms) 
    end 
end 

print('hello') 
sleep(500) -- sleep 500 ms 
print('world') 
1

मैं लुआ के साथ शुरू किया, लेकिन, तो मैंने पाया कि मैं सिर्फ अच्छे पुराने कमांड लाइन फ्लैश करने के बजाय परिणाम देखना चाहती थी। तो मैं सिर्फ मेरी फ़ाइल में निम्न पंक्ति जोड़ा और हे की सफ़ाई, मानक:

please press any key to continue... 

os.execute("PAUSE") 

मेरी उदाहरण फ़ाइल केवल एक प्रिंट है और फिर एक विराम के बयान तो मुझे यकीन है कि आपको लगता है कि यहां पोस्ट की जरूरत नहीं है हूँ।

मुझे पूर्ण स्क्रिप्ट के लिए चल रहे प्रक्रिया के CPU प्रभावों के बारे में निश्चित नहीं है। हालांकि डीबगिंग में कोड मध्य प्रवाह को रोकना उपयोगी हो सकता है।

1

मैं उन विंडो के लिए विश्वास करता हूं जिनका आप उपयोग कर सकते हैं: os.execute("ping 1.1.1.1 /n 1 /w <time in milliseconds> >nul एक साधारण टाइमर के रूप में। (हटाने "<>" जब मिलीसेकेंड में समय डालने)

2

आप उपयोग कर सकते हैं (वहाँ कोड के बाकी और >nul के बीच एक रिक्ति है):

os.execute("sleep 1") -- I think you can do every command of CMD using os.execute("command") 

या आप उपयोग कर सकते हैं:

function wait(waitTime) 
    timer = os.time() 
    repeat until os.time() > timer + waitTime 
end 

wait(YourNumberHere) 
0
cy = function() 
    local T = os.time() 
     coroutine.yield(coroutine.resume(coroutine.create(function() 
    end))) 
    return os.time()-T 
end 
sleep = function(time) 
    if not time or time == 0 then 
     time = cy() 
    end 
    local t = 0 
    repeat 
     local T = os.time() 
     coroutine.yield(coroutine.resume(coroutine.create(function() end))) 
     t = t + (os.time()-T) 
    until t >= time 
end 
+0

यह वास्तव में बहुत अच्छी तरह से काम करता है। – Descaii

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