Hi,
As Jeff mentions, [ns_info threads] can dump a list for you. You can also play with [ns_thread name newName] to set the name of the thread as a means to indicate what it's doing, e.g.,
ns_thread name "worker:waiting"
and then:
ns_thread name "worker:running"
However, the thread name and listing feature is more for debugging or monitoring purposes with a single coarse-grained lock around a single list so it may have trouble on a very busy server if threads are coming and going quickly (admit-ably this is a low probability problem).
One criticism of pthreads is the lack of a non-blocking join which could have allowed you to create non-detached threads and check if they've exited with a wait like you could with ordinary Unix processes. Solaris threads had a "wait for any thread" which wouldn't be too useful either unless you were 100% certain you were the creator of all detached threads. It looks like there is a non-standard extensions in Linux, i.e., pthread_tryjoin_np, and you could fiddle around with creating a Tcl command for this modeled on [ns_thread join] with non-detached threads.
But all that sounds hard. And, perhaps you're on Windows? So, maybe your own data structure is better. Just be careful to watch for race conditions with proper mutex locks and/or relying on atomic-features of nsv, something like this (caution: I just typed the below, not guaranteed to be correct or useful):
#
# Use a myWorkers nsv to store start and stop time of detached worker threads.
#
proc starterThinger {} {
set nextId [nsv_incr myWorkers nextId]
nsv_set myWorkers start,$nextId [ns_info time]
nsv_lappend myWorkers active $nextId
set tid [ns_thread begindetached [list workerProc $nextId]]
}
proc workerProc {myId} {
... do something useful ...
nsv_set myWorkers done,$myId [ns_info time]
... ok to die ...
}
proc checkerThinger {} {
set active {}
foreach id [nsv_get myWorkers active] {
if {[nsv_exists myWorkers done,$id]} {
nsv_unset myWorkers done,$id
nsv_unset myWorkers start,$id
... do something with knowledge thread died, perhaps the start and stop time are useful too ...
} else {
lappend active $id
}
}
nsv_set myWorkers active $active
}
The use of worker-pool specific id's instead of thread id's is a paranoia that thread id's could be re-used, perhaps quickly, fuddling things up. However, the checkerThinger proc has a race condition of scanning the active list and then reseting it -- the startThinger could have started a thread during the check. So, that at least is a known bug.
Anyway, all the above is likely overkill ... consider using [ns_info threads] first instead :)
Cheers
-Jim