{"id":349,"date":"2007-12-22T23:12:38","date_gmt":"2007-12-22T21:12:38","guid":{"rendered":"https:\/\/alax.info\/blog\/349"},"modified":"2007-12-22T23:12:38","modified_gmt":"2007-12-22T21:12:38","slug":"semaphores","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/349","title":{"rendered":"Semaphores"},"content":{"rendered":"<p><a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms685129.aspx\" title=\"Semaphore Objects\">Semaphore objects<\/a> are specific synchronization objects that maintain a counter that lock\/unlock the object on reaching specific predefined count. The counter make the object specific and different from other synchronization objects such as <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms682530(VS.85).aspx\">critical sections<\/a>, <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms684266(VS.85).aspx\">mutexes<\/a>, <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms682655(VS.85).aspx\">events<\/a>. After years of software development with a horde of threads and events it is the first time I needed to look towards semaphore.<\/p>\n<p>While it&#8217;s quite clear what exactly it does, a tiny sample would never hurt to understand thing better.  Good news is that ATL core classes offer a CSemaphore class (surprisingly not documented in <a href=\"http:\/\/msdn2.microsoft.com\/\">MSDN<\/a>).<\/p>\n<p>Semaphore magic goes below:<\/p>\n<p><!--more--><\/p>\n<blockquote><p><code>D:\\...\\SemaphoreSample01\\Release&gt;SemaphoreSample01.exe<br \/>\nTime 0000, Thread 05208: Main thread is initializing...<br \/>\nTime 0000, Thread 04132: Worker thread is initializing...<br \/>\nTime 0000, Thread 04132: Wait result 0<br \/>\nTime 0000, Thread 03284: Worker thread is initializing...<br \/>\nTime 0000, Thread 04132: Delay 4041<br \/>\nTime 0000, Thread 01360: Worker thread is initializing...<br \/>\nTime 0000, Thread 06020: Worker thread is initializing...<br \/>\nTime 0000, Thread 02444: Worker thread is initializing...<br \/>\nTime 0000, Thread 05392: Worker thread is initializing...<br \/>\nTime 0000, Thread 01036: Worker thread is initializing...<br \/>\nTime 0000, Thread 05088: Worker thread is initializing...<br \/>\nTime 0000, Thread 03284: Wait result 0<br \/>\nTime 0000, Thread 01360: Wait result 0<br \/>\nTime 0000, Thread 06020: Wait result 0<br \/>\nTime 0016, Thread 03284: Delay 4467<br \/>\nTime 0016, Thread 01360: Delay 4500<br \/>\nTime 0016, Thread 06020: Delay 5724<br \/>\nTime 4047, Thread 04132: Semaphore is about to be released<br \/>\nTime 4047, Thread 04132: Semaphore released, nOldCount 0<br \/>\nTime 4047, Thread 02444: Wait result 0<br \/>\nTime 4047, Thread 04132: Worker thread is terminating...<br \/>\nTime 4047, Thread 02444: Delay 5358<br \/>\nTime 4485, Thread 03284: Semaphore is about to be released<br \/>\nTime 4485, Thread 05392: Wait result 0<br \/>\nTime 4485, Thread 03284: Semaphore released, nOldCount 0<br \/>\nTime 4485, Thread 05392: Delay 4334<br \/>\nTime 4485, Thread 03284: Worker thread is terminating...<br \/>\nTime 4516, Thread 01360: Semaphore is about to be released<br \/>\nTime 4516, Thread 01036: Wait result 0<br \/>\nTime 4516, Thread 01360: Semaphore released, nOldCount 0<br \/>\nTime 4516, Thread 01036: Delay 5169<br \/>\nTime 4516, Thread 01360: Worker thread is terminating...<br \/>\nTime 5000, Thread 05088: Wait result 258<br \/>\nTime 5000, Thread 05088: Worker thread is terminating...<br \/>\nTime 5735, Thread 06020: Semaphore is about to be released<br \/>\nTime 5735, Thread 06020: Semaphore released, nOldCount 0<br \/>\nTime 5735, Thread 06020: Worker thread is terminating...<br \/>\nTime 8813, Thread 05392: Semaphore is about to be released<br \/>\nTime 8813, Thread 05392: Semaphore released, nOldCount 1<br \/>\nTime 8829, Thread 05392: Worker thread is terminating...<br \/>\nTime 9407, Thread 02444: Semaphore is about to be released<br \/>\nTime 9407, Thread 02444: Semaphore released, nOldCount 2<br \/>\nTime 9407, Thread 02444: Worker thread is terminating...<br \/>\nTime 9688, Thread 01036: Semaphore is about to be released<br \/>\nTime 9688, Thread 01036: Semaphore released, nOldCount 3<br \/>\nTime 9688, Thread 01036: Worker thread is terminating...<br \/>\nTime 10000, Thread 05208: Main thread is terminating...<\/code><\/p><\/blockquote>\n<p>The sample creates a semaphore object with a counter value of 4 (g_nSemaphoreCount) and creates 8 (g_nThreadCount) threads to synchronize on this semaphore with a timeout value of 5 seconds (g_nSemaphoreWaitTimeout).<\/p>\n<p>Semaphore would satisfy four requests according to its counter value and the rest of the threads would timeout on wait function call unless any of the successful threads release the lock.<\/p>\n<p>A successful thread chooses time interval during which it holds the lock pseudo-randomly between 4 and 6 seconds (g_nFixedSemaphoreLockDelay, g_nRandomSemaphoreLockDelay). The delays are 4041 ms,\u00a0 4467 ms, etc. asquoted above.<\/p>\n<p>Note that as soon as first thread that held the lock for 4041 ms releases it, because 4041 is less than 5000 then another thread is on time getting a lock on the semaphore too.<\/p>\n<p>Thus four threads are successful in waiting on semaphore from the start, 3 more threads locked the object before timeout value as soon as other threads release semaphore and the 8th thread failed to wait with a timeout result (Wait result 258).<\/p>\n<p>This is how semaphore works.<\/p>\n<p>Visual C++.NET 2005 source code can be downloaded <a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2007\/12\/semaphoresample01.zip\">here<\/a>, compiled binary &#8211; <a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2007\/12\/semaphoresample01exe.zip\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Semaphore objects are specific synchronization objects that maintain a counter that lock\/unlock the object on reaching specific predefined count. The counter make the object specific and different from other synchronization objects such as critical sections, mutexes, events. After years of software development with a horde of threads and events it is the first time I&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/349\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,21,13],"tags":[],"class_list":["post-349","post","type-post","status-publish","format-standard","hentry","category-atl","category-seriously","category-source"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=349"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/349\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}