|Frontier Tutorials / Working With Threads / How to Be Thread-Friendly|
In a threaded environment, your scripts need to be thread-friendly. This means they should, as much as possible, use local variables. Where they must use global or shared data and resources, they must use semaphores to avoid conflict with other threads. And they must allow other threads the opportunity to run, as well.
In some environments, threads are preemptive. This means that the operating system (or whatever other entity is managing the threads--Frontier, in this case) forces threads to give up control of the processor so other threads can run.
Frontier uses a cooperative threading model. This means that threads must explicitly yield to give other threads an opportunity to run.
Frontier provides two verbs that yield time to other threads: sys.systemTask and thread.sleepFor.
sys.systemTask yields the processor to other threads, then returns as soon as all other threads have had an opportunity to run.
thread.sleepFor yields the processor to other threads, and doesn't return until after a specified interval (in seconds) has elapsed.
In your threaded routines, you should yield frequently by calling one of these verbs. When to call which routine depends on your application, and on what your application is doing when you yield.
If your threaded routine stops in a tight loop to wait for something to happen, it should generally call thread.sleepFor rather than sys.systemTask. If you call sys.systemTask each time through a wait loop, your wait loop may consume a large fraction of the available processor power--even if it's doing no useful work! If you don't yield at all within your loop, you will hog the cpu (yes, that's a technical term!), and no other thread will be able to run while you're doing no useful work. If, on the other hand, you call thread.sleepFor, your loop will run only infrequently. For example, if you call thread.sleepFor(5), your loop will run once every 5 seconds.
If, on the other hand, you're doing a time-consuming operation, you don't want the user to think Frontier has locked up--if they think that, they're liable to kill Frontier and restart it, and your process would never complete! In this case, you should add occasional calls to sys.systemTask in strategic places. For example, if you're parsing a fixed-record data file one line at a time, call sys.systemTask from within the loop.. This allows you to parse your data file almost as fast as if you didn't yield, but the user can still do other work (or read Frontier tutorials!) while waiting for the data to be imported.