Fork and Suspend

In general MOO programs start at the first line and step through until they get to the end without pausing. There are some notable exceptions to this rule and I'll explain them here.


The easier concept of the two I'm going to present is the 'suspend()' function. When the program comes to a use of suspend in the code it stops executing for the amount of seconds given in the argument to the function. So for example, suspend(5); would wait for 5 seconds and then continue on with the rest of the code that follows it.

If you wanted your cat to sit around and do nothing for three seconds before reacting when you stroked it, you could write it as:

player:tell("You stroke ", this:title(), "."); 
player.location:announce(player:titlec(), " strokes ", this:title(), "."); 
before giving the happy or angry message.

In existing code you will also see suspend(0); quite often; especially inside for or while loops. So why would you want to wait for zero seconds?

MOO programs only have a limited amount of resources - measured in 'ticks'. The default amount available is 30,000. While this seems like more than enough, given that a built in function call uses up only 4 or so, in a long loop it can get used up pretty quickly. By suspending for zero seconds it allows other programs that are waiting to have a chance to execute, and thus the MOO can refresh the amount of ticks that your program has. Then when the other programs have had their chance, the MOO will come instantly back to yours.
So, if you get a Run out of Ticks message for a program with a loop in it, you might want to add suspend(0); into the loop.

Suspend can also be called without an argument. In this case the task will sleep indefinitely until it is either killed or resumed. For more information about this, see the page on task ids.


Whereas suspend puts a delay into the process, fork does something much more interesting; it splits the task into two separate programs in effect and both programs run simultaneously! A diagram of how the program runs would then look like a forked road with the code flowing down both of the ways at the same time.

fork is like the loop constructions - it starts with a line like:
fork (<variable>)
and ends with:

The lines between the begin and end lines, or the fork 'block', will be run as a new program and the current program will keep running at the same time using the code after the endfork line. The variable inside the brackets for fork is a number - the amount of seconds after which the code should start to execute. In this way it is similar to suspend as it can do things after a certain amount of time.
The following code will hopefuly show how this works in practice.

Add a verb to yourself called @forktest with no argument specifiers:
@addverb me:@forktest none none none
Then write the following code into it:

player:tell("Starting the fork test.");
fork (0)
  player:tell("This is from the fork block.");
  player:tell("This is from the fork block, 1 second later.");
player:tell("This is after the fork block.");
player:tell("This is after the fork block, 2 seconds later.");

Now compile and run the program (just type @forktest). The output should look like:

Starting the fork test.
This is after the fork block.
This is from the fork block.
This is from the fork block, 1 second later.
This is after the fork block, 2 seconds later.

Now try changing the fork (0) line to read instead: fork (2). Compile it and try running it again. You should get the output:

Starting the fork test.
This is after the fork block.
This is from the fork block.
This is after the fork block, 2 seconds later.
This is from the fork block, 1 second later.
That's because the the code in the fork block only starts executing after 2 seconds now rather than instantly when we had 0 there.

There's a more complex usage of fork on the page about tasks

Last modified: Fri Jul 7 11:52:34 GMT 2000