From: mili on
Hi all,

I am in need of semaphores. I want to synchronize resource access
between several processes where one process writes and several other
reads that resource.

Is there a semaphore extension already existing? (searched long
without any success)

Thanks,
Milad
From: mili on
BTW: I found already that package http://web.uvic.ca/~erempel/tcl/Semaphore/Semaphore.html
..
But the download links are down and I couldn't find the package
anywhere else.
Perhaps someone has a working link?

From: tom.rmadilo on
On Nov 20, 6:01 am, mili <mila...(a)web.de> wrote:
> BTW: I found already that packagehttp://web.uvic.ca/~erempel/tcl/Semaphore/Semaphore.html
> .
> But the download links are down and I couldn't find the package
> anywhere else.
> Perhaps someone has a working link?

You can compile AOLserver (using your version of Tcl) and then use
nstclsh instead of tclsh.

What you get are several new primitives: ns_mutex, ns_sema, ns_cond,
but most important:

ns_rwlock: http://rmadilo.com/files/nsapi/ns_rwlock.html

But you also might check if the threads package includes this
primitive. I've never used a rw lock. The reason is that it is much
easier to have the writer write to a temp file and then do an atomic
rename. This has the advantage that the time required to write is
eliminated as well as many other complications. But if your OS does
not support atomic rename, you must use a read-write lock and control
all access to the file, making sure everyone uses the rw lock.

Also, just as a general statement, it is very difficult to find a use
case for semaphores. I tried, but they usually end up inside something
bigger like a read-write lock.

But if you really want to be safe and allow reading/writing of the
same file at the same time, use an atomic rename.

Here is a link to an example which uses a mutex, but also an atomic
rename:

http://www.junom.com/gitweb/gitweb.perl?p=tnt.git;a=blob;f=packages/datastore/tcl/datastore-procs.tcl;hb=HEAD#l418

Just the lock/rename:

set LockID [lock $store]
if {[catch {
set FD [open ${dataFileroot}.tmp w+]
fconfigure $FD -translation binary -encoding binary
puts $FD "$out"
close $FD
file rename -force ${dataFileroot}.tmp $dataFileroot
} err ]} {
unlock $store $LockID ;# Note: FD will be closed automatically, if
open
error $err "::tnt::datastore::save error saving store $store"
}
unlock $store $LockID

Also note that the lock covers many potential files, $store is an sha1
hash and the lock is determined by the last few chars of the hex rep
(usually just the last char), so the lock is almost like a reverse
semaphore: many files, one reader/writer. Deadlocks are avoided
because reads and writes do not contain recursive code (which is easy
to audit).
From: Donal K. Fellows on
On 21 Nov, 00:34, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
> ns_rwlock:http://rmadilo.com/files/nsapi/ns_rwlock.html
>
> But you also might check if the threads package includes this
> primitive.

The thread package does include read-write locks.

> But if your OS does not support atomic rename, you must use a
> read-write lock and control all access to the file, making sure
> everyone uses the rw lock.

Is there an OS without atomic renames of files within the same
directory? Even Windows has got that right for a long time now.
(Moving between filesystems is something else.) For goodness' sake,
even networked filesystems get it right (it's one of the few atomic
operations that they do get right - along with open() with O_CREAT|
O_EXCL flags - because it is a single message each way).

Donal.
From: tom.rmadilo on
On Nov 21, 12:44 am, "Donal K. Fellows"
<donal.k.fell...(a)manchester.ac.uk> wrote:
> On 21 Nov, 00:34, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
>
> > ns_rwlock:http://rmadilo.com/files/nsapi/ns_rwlock.html
>
> > But you also might check if the threads package includes this
> > primitive.
>
> The thread package does include read-write locks.
>
> > But if your OS does not support atomic rename, you must use a
> > read-write lock and control all access to the file, making sure
> > everyone uses the rw lock.
>
> Is there an OS without atomic renames of files within the same
> directory? Even Windows has got that right for a long time now.
> (Moving between filesystems is something else.) For goodness' sake,
> even networked filesystems get it right (it's one of the few atomic
> operations that they do get right - along with open() with O_CREAT|
> O_EXCL flags - because it is a single message each way).
>

Yeah, too bad the OP said "resource" and not file. But I can't think
of a non-file resource which could use a rw lock.

If the resource is an array available to all threads, use the thread
package and the tsv arrays. They use mutex buckets, multiple arrays
share some number of mutexs, probably a hash of the array name.

Works really well.

Come to think of it, it seems the thread package would be required to
create the issue to begin with. If you only have one thread I'm not
sure how you could ever create the need to synchronize access to
anything in Tcl.