|
Resources - Frontier - Semaphores
Last Modified 6/4/99.
To transport stuff across the country. You'll usually see 'em on the interstates but they run on the
smaller roads, too, depending on the road's weight restrictions.
I saw this question posted to the Frontier-talk list in 1994. I was glad to see it because I didn't know
what a semaphore was, either, but didn't want to be the one to ask. Unfortunately, I was so dazzled
by the wit I remembered nothing more about semaphores than the cute little pun. I errupted into
giggles at the mere mention of the word when my colleague brought it up recently as the solution to
my problem.
The problem was with a Frontier cgi that worked with a third party database. The cgi set a database
cell, ran a database script, then returned the contents of another database cell. When more than one
person hit the cgi with different data, sometimes the first person would get the results that the
second person was expecting.
The cgi was setting the cell for the first person, then the second person's request came in and reset
the cell before the database script could run so that the first results out of the program reflected the
second request instead of the first one.
In Filemaker, there is a begin transaction and an end transaction function that you can call so that
what goes on in between is not interrupted. Unfortunately this was not Filemaker.
Since I didn't have access to any begin and end transaction with this database, I had to control the
threads coming in to the database. I had to create a variable that would become occupied by one
thread and not become unoccupied until that thread was finished. As soon as it was finished, the
next thread could occupy it and run through that part of the script. The waiting threads had to be
arranged in an array so that I could keep track of the order. While they were waiting, they would be
put to sleep. You can see all these thread commands by typing "thread" into the "jump..." option
under the Frontier Main menu.
If you still can't picture this, think of the little bathroom on a long, crowded flight. The people that
need to use it are threads. When someone goes in, the little sign says "occupied", so the rest of the
threads go back to their seats and sleep until the first thread comes out and the sign says
"unoccupied". Then the next thread goes in and so on...(worse than the semi pun?)
I was not looking forward to having to work with all these thread functions - making and managing
the array - I just didn't want to deal with it. That's when my colleague mentioned "semaphores". I
remembered that joke, so I knew there must be a command for a semaphore, somewhere. I searched
the Frontier site, and sure enough, found it documented on a page that talks about Frontier's
"undocumented features".
It turned out to be very simple. There's a semaphores.lock(name, ticks) and a
semaphores.unlock(name). Perfect nomenclature for the flight example. Think of it as locking that
bathroom door. Where ever you want your threads to start sorting through single file, you issue the
semaphores.lock(name, ticks) function. Name is just any name that you want to give to the
semaphore session, so you can have more than one semaphore happening in the same script. You
don't have to define this variable before hand. Just make sure you use the same string when you
issue the unlock. Ticks are the number of ticks that you could possible stand to have a thread wait.
For my purposes, I set it really high so WebStar would time out first and I wouldn't have to deal
with it. At the end of the procedure make sure you issue semaphores.unlock(name).
An example would look like:
semaphores.lock(mysemi, 900)
with object the_database
set cell[whatever]
do script[somescript]
foo==get cell[someother]
semaphores.unlock(mysemi)
Without the semaphore code, your hits could be coming in and hitting the script willynilly setting
the cell who knows how many times before the poor script had a chance to finally run. With the
semaphore code your threads are allowed in one at a time, uninterrupted, so there's no chance of
getting someone else's results.
One might ask, why bother with the thread commands when we have semaphores? Well, depending
on your data, some requests may come first. If you can identify your boss by his IP address, you
may want to put him at the head of the line. On the other hand, there are other threads you may want
to put to sleep forever. Having the thread commands allows you the freedom to decide, but if all
you want to do is hustle them through in the order they arrived, the simple semaphore solution
works great!
Cheers to the punster who helped me remember that there was a semaphore option! If you ever
happen to read this - I'm still laughing!
Originally posted 7/7/98
|