lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Title: Grupo Hasar
Yes, I said "local variables" but I was mentally including the function arguments too. I realize now that calling the object returned by coroutine.create() a "thread" was probably an unfortunate choice. As you pointed out, threads allow parallel or pseudo-parallel execution, while there is no parallelism with coroutines.

As an aside, it is possible to implement a cooperative multitasking system with coroutines. One would need one coroutine for each task plus a scheduler. The scheduler is a loop that keeps picking the first task from a queue of ready tasks (if any) and resumes it. The ready queue and other task queues could be sorted on priority or just FIFO.

function scheduler()
    while true do
        current_task = pop_front(ready_queue)
        if current_task then coroutine.resume(current_task) end
        end
    end
end


One can easily write primitives that would allow tasks to yield, block while waiting for some event and be awakened by an event, for example:

function yield()
    push_back(ready_queue, current_task)
    coroutine.yield()
end

function wait(event)
    push_back(task_queue[event], current_task)
    coroutine.yield()
end

function signal(event)
    local task = pop_front(task_queue[event])
    if task then push_back(ready_queue, task) end

    -- (Only for systems that support task priorities:)
    -- If task has higher priority than current_task, call
    -- coroutine.yield() here so the scheduler may resume it.
end

Based on these simple primitives things like semaphores, mutexes, message-passing etc. can be easily devised. I will try to write a multitasking module on these lines.

As you pointed out, a system like this would emulate cooperative multithreading faithfully in a single processor environment only, since only one coroutine can be active at any time, while a multi-processor system can run one thread on each processor.

Regards,
Hugo


David Kastrup escribió:
Hugo Etchegoyen <hetchegoyen@hasar.com> writes:

  
If I understood well, then one might say that resuming is like
calling and yielding is like returning, the only difference being
that the callee keeps the values of its local variables between
invocations, and each time it is called it starts executing at the
instruction following the last yield. Right?
    
And it keeps its whole call stack, too.  You can yield in the middle
of a called function.  Just like the caller (so coroutines are an
emancipation of subroutines, but there remain subtle differences).

Basically right.

  

--

Ing. Hugo Eduardo Etchegoyen
Gerente Dto. Software de Base

Compañía Hasar | Grupo Hasar
Marcos Sastre y José Ingenieros
El Talar. Pacheco
[B1618CSD] Buenos Aires. Argentina
Tel [54 11] 4117 8900 | Fax [54 11] 4117 8998
E-mail: hetchegoyen@hasar.com
Visítenos en:
www.hasar.com
Información legal y política de confidencialidad: www.grupohasar.com/disclaimer