Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

difference of spawn() and coroutine?

Asked by
noposts 75
8 years ago

not really much to say because the title is self-explanatory. had troubles tryna understanding them, can't find much in the wiki.

0
Imo, there isn't really much of a difference; however, in terms of use, I believe using `coroutine` has more of an advantage for /some/ things. TheeDeathCaster 2368 — 8y

1 answer

Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago
Edited 8 years ago

Coroutines are a very powerful feature that allow two executions to "work together".

Two coroutines use coroutine.resume and coroutine.yield to communicate with each other and "hand off" execution.


The simplest way for two coroutines to "work together" is to completely ignore each other and just take turns doing work. This is how ROBLOX gets the appearance of "multitasking": wait() causes the current coroutine to stop working and lets another coroutine start working.

If you're only using coroutine to make two threads work "at the same time", don't use coroutine.

Instead, use spawn to create a "thread" in the background.

See this thread for examples of (not) using spawn to great effect.


Consider the following function that produces prime numbers:

01-- a prime number is any number larger than 1 not divisible
02-- any smaller (prime) number
03function computePrimes()
04    local primes = {}
05 
06    while #primes < 1000 do
07        local isPrime = true
08        for _, smallerPrime in ipairs(primes) do
09            -- if `i` is divisible by `smallerPrime`
10            if i % smallerPrime == 0 then
11                isPrime = false
12            end
13        end
14 
15        if isPrime then
View all 21 lines...

The above function produces a list; you can use a simple loop to print out the first 1000 primes:

1for _, prime in ipairs(computePrimes()) do
2    print(prime)
3end

Or you could do something like, compute the sum of all of the primes under 10000:

1local sum = 0
2for _, prime in ipairs(computePrimes()) do
3    if prime >= 10000 then
4        break
5    end
6    sum = sum + prime
7end
8print(sum)

There are two main problems with this approach.

1) computePrimes() might not have made enough primes; it's possible it stopped too early 2) computePrimes() might have wasted time making way more primes than we need; it's possible the loop doesn't even cover most of the list.

We could plumb this information into computePrimes, but that would make computePrimes much more complicated.

The solution is to use coroutines; then computePrimes will be a generator that produces 1 prime at a time:

01primeComputer = coroutine.wrap(function()
02    local primes = {}
03 
04    for i = 2, math.huge do
05        local isPrime = true
06        for _, smallerPrime in ipairs(primes) do
07            -- if `i` is divisible by `smallerPrime`
08            if i % smallerPrime == 0 then
09                isPrime = false
10            end
11        end
12 
13        if isPrime then
14            table.insert(primes, i)
15            -- `prime` is the value that this generator
16            -- will return each time it is called
17            coroutine.yield(i)
18        end
19    end
20end)

I use coroutine.wrap as a convenience, I won't give an example here that uses coroutine.resume / coroutine.create manually.

Now, we can write our loop and compute exactly the set of primes we want:

01local sum = 0
02while true do
03    -- ask for one more prime
04    local prime = primeComputer()
05 
06    if prime >= 10000 then
07        break
08    end
09    sum = sum + prime
10end
11 
12print(sum)
0
hm thanks for making me understand. also appreciate you typing those up noposts 75 — 8y
Ad

Answer this question