Semaphore count
-
Does anyone know how to determine the current count associated with a semaphore? Let me explain. I have a server app that creates a background thread every time a client app makes a request. Before each background thread is created my app goes through ::WaitForSingleObject(m_hSemaphore, INFINITE) to ensure that I do not exceed a safe number of concurrent threads. When the background thread finishes its work, it calls ::ReleaseSemaphore(m_hSemaphore, 1, NULL) to balance the semaphore count. There are times that I need to wait for all background threads to end (for example when the program ends). If I could check for the current semaphore count, I would know how many background threads are still running. Currently I'm keeping a counter (protected with a critical section) that is incremented when the background thread starts and decremented when it ends. This works but it seems somewhat silly since this information is implicit in the semaphore object. There is yet another possibility, The 3rd argument of ::ReleaseSemaphore() is a pointer to a LONG that receives the previous count. However, it seems to me that there is a problem here since you have several threads writing to this LONG at about the same time without any thread synchronization mechanism. Semanticaly, I need something like ::GetSemaphoreCount(m_hSemaphore). So far as I know such function does not exist. Thanks, Julberto Danray
-
Does anyone know how to determine the current count associated with a semaphore? Let me explain. I have a server app that creates a background thread every time a client app makes a request. Before each background thread is created my app goes through ::WaitForSingleObject(m_hSemaphore, INFINITE) to ensure that I do not exceed a safe number of concurrent threads. When the background thread finishes its work, it calls ::ReleaseSemaphore(m_hSemaphore, 1, NULL) to balance the semaphore count. There are times that I need to wait for all background threads to end (for example when the program ends). If I could check for the current semaphore count, I would know how many background threads are still running. Currently I'm keeping a counter (protected with a critical section) that is incremented when the background thread starts and decremented when it ends. This works but it seems somewhat silly since this information is implicit in the semaphore object. There is yet another possibility, The 3rd argument of ::ReleaseSemaphore() is a pointer to a LONG that receives the previous count. However, it seems to me that there is a problem here since you have several threads writing to this LONG at about the same time without any thread synchronization mechanism. Semanticaly, I need something like ::GetSemaphoreCount(m_hSemaphore). So far as I know such function does not exist. Thanks, Julberto Danray
If you have handles to the running threads, you can wait on them all with
WaitForMultipleObjects()
, which will block until all the threads exit.--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
-
Does anyone know how to determine the current count associated with a semaphore? Let me explain. I have a server app that creates a background thread every time a client app makes a request. Before each background thread is created my app goes through ::WaitForSingleObject(m_hSemaphore, INFINITE) to ensure that I do not exceed a safe number of concurrent threads. When the background thread finishes its work, it calls ::ReleaseSemaphore(m_hSemaphore, 1, NULL) to balance the semaphore count. There are times that I need to wait for all background threads to end (for example when the program ends). If I could check for the current semaphore count, I would know how many background threads are still running. Currently I'm keeping a counter (protected with a critical section) that is incremented when the background thread starts and decremented when it ends. This works but it seems somewhat silly since this information is implicit in the semaphore object. There is yet another possibility, The 3rd argument of ::ReleaseSemaphore() is a pointer to a LONG that receives the previous count. However, it seems to me that there is a problem here since you have several threads writing to this LONG at about the same time without any thread synchronization mechanism. Semanticaly, I need something like ::GetSemaphoreCount(m_hSemaphore). So far as I know such function does not exist. Thanks, Julberto Danray
You are correct, the function you want does not exist. In your case, it's not really needed. Knowing how many threads are active isn't that useful since, during shutdown, all that matters is that you safely terminate all the threads. This can be done in a myriad of ways. Also, sounds to me like you may want to consider using I/O completion ports. They are a little tricky to understand, but here's one article: http://www.sysinternals.com/Information/IoCompletionPorts.html[^] Jeffrey Richter has a pretty good discussion on these in his books Programming Applications for Microsoft Windows http://www.amazon.com/gp/product/1572319968/sr=1-5/qid=1156371108/ref=sr_1_5/102-5249029-6251347?ie=UTF8&s=books[^]and Programming Server-Side Applications for Microsoft Windows 2000 http://www.amazon.com/gp/product/0735607532/sr=1-9/qid=1156371151/ref=sr_1_9/102-5249029-6251347?ie=UTF8&s=books[^] (Both are excellent books.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
If you have handles to the running threads, you can wait on them all with
WaitForMultipleObjects()
, which will block until all the threads exit.--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
That's a good idea but I want to emphasize that the motivation to determine the number of active threads via the semaphore handle is to simplify the code. The mechanism I'm currently using gets the job done. However, complexity is the enemy of good code. A solution based on a GetSemaphoreCount-like function would be not only simple and elegant but very understandable to anyone maintainig the code. For the time being it is likely that I will continue to use the method descrived in my original post. Julberto
-
You are correct, the function you want does not exist. In your case, it's not really needed. Knowing how many threads are active isn't that useful since, during shutdown, all that matters is that you safely terminate all the threads. This can be done in a myriad of ways. Also, sounds to me like you may want to consider using I/O completion ports. They are a little tricky to understand, but here's one article: http://www.sysinternals.com/Information/IoCompletionPorts.html[^] Jeffrey Richter has a pretty good discussion on these in his books Programming Applications for Microsoft Windows http://www.amazon.com/gp/product/1572319968/sr=1-5/qid=1156371108/ref=sr_1_5/102-5249029-6251347?ie=UTF8&s=books[^]and Programming Server-Side Applications for Microsoft Windows 2000 http://www.amazon.com/gp/product/0735607532/sr=1-9/qid=1156371151/ref=sr_1_9/102-5249029-6251347?ie=UTF8&s=books[^] (Both are excellent books.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
Thanks for the links to the article and books. I'll look into them. By the way, it is important to me to know when all threads are done so the code can proceed to release resources. The background threads are somewhat short-lived since they just generate a synthetic HTML page and send it to the requesting client. The foreground thread waits until all background threads (if any) are done and then deletes the server object. Julberto
-
Thanks for the links to the article and books. I'll look into them. By the way, it is important to me to know when all threads are done so the code can proceed to release resources. The background threads are somewhat short-lived since they just generate a synthetic HTML page and send it to the requesting client. The foreground thread waits until all background threads (if any) are done and then deletes the server object. Julberto
I don't like polling, so I always use WaitForMultipleObjects() I would have liked if they made it possible to have an event signaled every time the sempahore is in an unused state. You could simulate this by writing a small function with a critical section with the semaphore code inside and a counter.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke
-
Does anyone know how to determine the current count associated with a semaphore? Let me explain. I have a server app that creates a background thread every time a client app makes a request. Before each background thread is created my app goes through ::WaitForSingleObject(m_hSemaphore, INFINITE) to ensure that I do not exceed a safe number of concurrent threads. When the background thread finishes its work, it calls ::ReleaseSemaphore(m_hSemaphore, 1, NULL) to balance the semaphore count. There are times that I need to wait for all background threads to end (for example when the program ends). If I could check for the current semaphore count, I would know how many background threads are still running. Currently I'm keeping a counter (protected with a critical section) that is incremented when the background thread starts and decremented when it ends. This works but it seems somewhat silly since this information is implicit in the semaphore object. There is yet another possibility, The 3rd argument of ::ReleaseSemaphore() is a pointer to a LONG that receives the previous count. However, it seems to me that there is a problem here since you have several threads writing to this LONG at about the same time without any thread synchronization mechanism. Semanticaly, I need something like ::GetSemaphoreCount(m_hSemaphore). So far as I know such function does not exist. Thanks, Julberto Danray