Domanda

I want to figure out a way to create an object by passing a function into it, having it be sent to a coroutine, then have a few function such as start() stop() and status() It could look like this, but i don't know how to implement this.

local Process = {}
Process.__index = Process

function newProcess(name,func)
  local self = setmetatable({}, Process)
  self.name = name
  self.func = func
  return self
end

This would just make the initialization for the process, by passing a name and function. I would like to add some methods too, below. (this is where i need help implementing)

function Process:start()
  self.thread = -- create coroutine here
  self.thread -- Resume the coroutine here
end

Creates a coroutine with the function variable "self.func" Then starts the coroutine. I have the initialization in the start function so it can be run multiple times. This is where i am having trouble

function Process:stop()
  -- Stops the running coroutine (shutdown or in case i need to end i)
end

I may need this greatly in the future but i have no idea how to implement it. Basically use the self.thread variable created above

function Process:status()
  -- Maybe return the coroutine.status?
end

Thank you for your help. Thanks!

È stato utile?

Soluzione

You are very close. Coroutines are cooperative threads, so the function you pass to process will have to call coroutine.yield (ideally, often). Also Process needs resume() so the "thread" can do more work. The coroutine can be stopped anytime from outside the coroutine while not executing the coroutine: just don't resume it, and nil it. It can be stopped anytime from within the coroutine by not yielding but returning. It would look something like this (not tested for bugs):

function Process:start()
    self.thread = coroutine.create(self.func)
    self:resume() -- run to next yield
end

function Process:resume()
    coroutine.resume(self.thread)
end

function Process:stop() -- from "outside" thread
    self.thread = nil
end

function Process:status()
  return coroutine.status(self.thread)
end

Make sure you look at Lua ref manual sections 2.11 for example of how to structure your function using coroutine.yield, and section 5.2 for details on coroutine module.

You could have multiple threads:

function func1() ... end
function func2() ... end
p1 = newProcess("func1", func1)
p2 = newProcess("func2", func2)
p1:start() -- runs func1 to its first yield
p2:start() -- runs func2 to its first yield
p1:resume() -- runs func1 to its second yield
p2:resume() -- runs func2 to its second yield

Note that the above will not work if you have func1 as such:

function func1()
    sleep(100) -- seconds
end

But it will work if func1 is this:

function func1()
    for i=1,100 do 
         sleep(1)
         coroutine.yield()
    end
end

Both sleep the same amount of time (100 s) but the first version will return only after 100 s, whereas the second one can be called 100 times, which gives the same results as single core multiple threads. Note: sleep is pseudocode, it is not available in Lua; and sleep is only used to illustrate a function that takes a large amount of time to do something that can broken down into many little chunks.

Altri suggerimenti

You can't do that, since coroutines are a form of cooperative multitasking. This means that only one coroutine is running each time and that the only way to transfer control back from the running coroutine is for the coroutine itself to yield at an appropriate point.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top