Some more thoughts on multithreading

Nonsanity form at nonsanity.com
Wed Feb 9 22:33:43 CST 2011


On Wed, Feb 9, 2011 at 6:42 PM, Bob Sneidar <bobs at twft.com> wrote:

> I wonder why a lot of people think the threaded stack has to be sandboxed?
> The engine opened it, the engine knows how to communicate with it and other
> stacks. I really don't understand why a threaded stack would be inaccessible
> to other stacks. The only thing is that a threaded stack or perhaps a
> threaded command or function would be able to process independently of the
> main thread running everything else.
>
> But again, I am not a high level programmer. I can imagine how in C you
> would need to manage all the locks and threads because there is no IDE that
> is running. You have to write your own IDE so to speak. In LiveCode, the IDE
> is running all the time, and it is the process that would open any thread,
> so it would have full access to that process, being the "parent", wouldn't
> it? Or am I missing something?
>
> Bob
>


Heya Bob.

Lets say we're having dinner together blindfolded, and we both reach for the
salt shaker at the same time. What happens?

Two scripts, running at the same time, both trying to read and modify the
same variable. The data is going to get mangled.

This doesn't HAVE to happen in one is careful and keeps in mind these sort
of dangers when programming with multiple threads, and if the right tools
are available to prevent it... And they are used correctly.

Serial port reading in LC is already multi-threaded. You can tell it to read
until a particular time or character, and send you an event when its done.
There is zero further interaction between that read thread and the main
thread. In this case it exits just after sending the message, but pretend it
was extended to continue to exist, sending another callback event whenever
the trigger happens. To stop it, you send IT a message.

But what if it started putting the data it reads into a, for example, stack
property called SerialData. I make the callback script like so:

get the number of chars in the SerialData of this stack
repeat with a = 1 to it
    put char it & return after fld 1
end repeat

So when (my mythical) looping serial read sends the callback (upon reading a
CR, for example) that script is begun. But because it's now a looping serial
read, it starts reading more off the port. I might be in the middle of my
loop when it gets a new line of data and puts it into the SerialData
property.

Now my script was in the middle of looping through that data and it changed.
Horrible mess.

This sort of thing is prevented in other languages that support threading
with semaphores and critical sections. These lock a variable so that only
one thread can access it at a time, or lock a section of code so that other
threads are paused while it executes. You put them in places you know the
two threads will be otherwise stepping on each other's toes. But knowing
WHEN these tools are necessary is key to good multi-threaded programming,
use them too often and the script is bogged down with accounting. Use them
wrong and you could end up with both threads waiting for the same salt
shaker...

You could teach the IDE to do all this for you, but it wouldn't be very
efficient at it, and the added overhead of all those locks will slow
everything down. There's no generic way to allow full access without a
significant hit to speed. (Or an embedded AI that can look at all the code,
understand where each script might be in conflict with another under all
data conditions, and put locks around those points.)

Now I know how to use a semaphore, as I program in C languages for a living,
but I'd hate to see them in LC. It would lose that ease of programming it is
famed for. But I would like to see threads, and sandboxing can make that
happen...


 ~ Chris Innanen
 ~ Nonsanity


More information about the use-livecode mailing list