jamin@cogsci.berkeley.edu (Sugih Jamin) (10/21/89)
In article <1989Oct19.143604.21001@rpi.edu> ander@pawl.rpi.edu (Michael R. Primm) writes: > >Threads are easy to use and much more useful than fork()ing around :-). > I am having problem dynamically creating and killing threads. Suppose I am a function that gets called everytime a thread is to be spawned. If I allocate a stack for the thread in my own stack, then that stack is going to get de-allocated everytime I exit. If I using the heap space for the thread stack, who will be freeing it? Definitely not the thread itself? Am I suppose to manage all those stacks also? Such is not the case in Mach, I think. Another question relating to threads, do you know how to tell if you have any thread running? Some API calls that serve an anologous purpose to DosCWait(), but for threads will be nice. According to all I have read on OS/2 semaphores, it seems like not only don't they support counting semaphores, they don't even eliminate the problem of race condition because any thread could be scheduled next. OS/2 has three different kinds of semaphores with ten(?) semaphore functions, yet none of them are as powerful as the one defined by Dijkstra? What I want is a counting semaphores with a FIFO queue. Sometime ago somebody wrote an article in the Microsoft Systems Journal showing how one could "easily" implement a counting semaphore using the available APIs. But the counting semaphore he showed did not have a FIFO queue associated with it, so one still has the race condition. Please correct me if I am wrong. sugih
ejp@bohra.cpg.oz (Esmond Pitt) (10/24/89)
In article <32054@ucbvax.BERKELEY.EDU> jamin@cogsci.berkeley.edu.UUCP (Sugih Jamin) writes: >Am I suppose to manage all those stacks also? I'm afraid so. >Another question relating to threads, do you know how to tell if you have >any thread running? Some API calls that serve an analogous purpose to >DosCWait(), but for threads will be nice. You can roll your own DosTWait() (wait for thread) fairly reliably. You just code a sleep loop which does something harmless to the thread like, say, attempting to get its priority. When you gets the No Such Thread error (sorry, no manual handy), the thread has finished. This is useful in waiting for the thread to finish so you can dispose of its stack. The only problem is that the threadid might be quickly re-used between the old thread terminating and a new one starting; this problem can be gated away. They really should have put in a DosTWait() and automatic stack allocation, though. >According to all I have read on OS/2 semaphores, it seems like not only don't >they support counting semaphores, they don't even eliminate the problem of >race condition because any thread could be scheduled next. OS/2 has three >different kinds of semaphores with ten(?) semaphore functions, yet none of >them are as powerful as the one defined by Dijkstra? What I want is a counting >semaphores with a FIFO queue. Sometime ago somebody wrote an article in the >Microsoft Systems Journal showing how one could "easily" implement a counting >semaphore using the available APIs. But the counting semaphore he showed >did not have a FIFO queue associated with it, so one still has the race >condition. Please correct me if I am wrong. Yes, sorry, they should have got that right too. -- Esmond Pitt, Computer Power Group ejp@bohra.cpg.oz
robertre@microsoft.UUCP (Robert Reichel ms2) (10/25/89)
In article <32054@ucbvax.BERKELEY.EDU> jamin@cogsci.berkeley.edu.UUCP (Sugih Jamin) writes: >I am having problem dynamically creating and killing threads. Suppose I am a >function that gets called everytime a thread is to be spawned. If I allocate >a stack for the thread in my own stack, then that stack is going to get >de-allocated everytime I exit. If I using the heap space for the thread >stack, who will be freeing it? Definitely not the thread itself? >Am I suppose to manage all those stacks also? Such is not the case in Mach, >I think. You need to manage your own stacks. There are a couple of ways I can think of to free a stack correctly, I'm sure there are more: Thread A Thread B Take Sem Wait on Sem DosEnterCritSet (turns off thread switching for the process) Release Sem DosExit Free B's stack The key point to remember is that DosExit clears an existing critical section. If you don't want to do the EnterCritSec (which is a bit rude since it pretty much shuts down your application) you can have A and B wait on a system semaphore and have A wake up with ERROR_SEM_OWNER_DIED. >Another question relating to threads, do you know how to tell if you have >any thread running? Some API calls that serve an anologous purpose to >DosCWait(), but for threads will be nice. This does not currently exist, but may in the future. Right now you have to have to keep track of who you've spun off. Most apps I've written somewhere have a bit array corresponding to thread id's, so I can scan it to see who's alive. >According to all I have read on OS/2 semaphores, it seems like not only don't >they support counting semaphores, they don't even eliminate the problem of >race condition because any thread could be scheduled next. OS/2 has three >different kinds of semaphores with ten(?) semaphore functions, yet none of >them are as powerful as the one defined by Dijkstra? What I want is a counting >semaphores with a FIFO queue. Sometime ago somebody wrote an article in the >Microsoft Systems Journal showing how one could "easily" implement a counting >semaphore using the available APIs. But the counting semaphore he showed >did not have a FIFO queue associated with it, so one still has the race >condition. Please correct me if I am wrong. I'm sure it's possible to do what you're trying to do, but I haven't done it yet and don't have the time at the moment. As far as FIFO goes, the scheduler is priority based, meaning that the highest priority thread waiting on a resource will be the first one scheduled, regardless of when he did the wait. This prevents low priority threads from holding resources needed by high priority guys and gumming up the works. As far as threads with equal priority goes, you will probably see FIFO response within a given priority group, but it isn't guaranteed. Disclaimer: My opinions are my own, and do not reflect the opinions or policies of Microsoft. I also reserve the right to be wrong. -- Robert Reichel robertre%microsof@beaver.washington.edu or {decvax,uunet,uw-beaver}!microsoft!robertre
ander@pawl.rpi.edu (Michael R. Primm) (10/25/89)
For the stack allocation problem, one user solution I've though of may be the use of a "watchdog" thread. Each stack that you allocate for a thread would have a RAM semaphore associated with it which starts off being "set". When a threat possessing such a stack wishes to terminate, it "clears" the semaphore and exits. The one problem is being sure that the thread is able to exit before the stack gets reused. But, anyway, the watchdog would hang out waiting for stack semaphores to "clear", and would free the storage after a "reasonable delay" (long enough to be sure the thread was able to exit after the semaphore was cleared). Anyway, while its pretty kludgy, it may be a possible route to consider. --Mike Primm
bobf@lotus.com (Bob Frankston (BFrankston)) (10/25/89)
Note that semaphores are associated with a process and not a thread and thus can't be used to detect the death of a thread. If the thread terminates cleanly, you can have it send a message to a queue announcing its demise. You can have a separate thread waiting on the queue that frees the resources for the departed tthreads. [Opinions are my own and do not necessarily represent Lotus]