Click here to Skip to main content
Click here to Skip to main content
Go to top

Using Win32 Semaphores in C#

, 30 Sep 2002
Rate this:
Please Sign up or sign in to vote.
How to use Windows semaphores in C# to share access to a system resource between many processes.

Screenshot

Introduction

Some applications need to share access to a restricted resource in a coordinated manner on one PC, like a dodgy print driver to which only one application can print at a time. All preemptively multitasking operating systems like Windows and Unix provide a mechanism called semaphores with which several running applications can coordinate access to restricted resources. In my case, I want to make sure that only one application at a time is trying to print a document to my dodgy print driver.

Explanation

Semaphores are named objects in the operating system. If several applications ask the operating system for a semaphore with the same name, then each application will be given a link to the same semaphore in the operating system. Name your semaphores something which you find meaningful and that all application sharing the resource must know. In my code sample I have named the semaphore "sem_DotNetExample" but you should name your semaphore after the resource it is being used to coordinate access to, like "sem_DodgyPrintDriver". Each semaphore keeps a count of how many applications can concurrently use the resource. In my case, I only want one application to use the resource at a time and other applications requesting to use the resource should wait until the resource becomes available. When the semaphore is created the operating system is told how high the count for the semaphore is and each time an application uses the semaphore, the count is decremented. If the count is zero when an application tries to use the semaphore, the application goes into an efficient waiting state, consuming very little CPU time until another application releases the resource. When your application has finished using the resource, it releases the semaphore, incrementing the availability count of the semaphore. Finally when your program shuts down it should clean up and delete its reference to the semaphore.

The Windows operating system provides many functions for working with semaphores, all of which are in the kernel32 library. The source code provides maps to these kernel functions and then makes the calls to the operating system when the application's buttons are clicked by a user. The way to map these functions in the kernel to C# methods is as follows. A working encapsulation of the semaphore functionality is included in the Semaphore class available in the source code download should you wish to include this functionality in your own projects.

[DllImport("kernel32", EntryPoint="CreateSemaphore",
           SetLastError=true,CharSet=CharSet.Unicode)]
private static extern uint NT_CreateSemaphore(
    SecurityAttributes auth,
    int initialCount,
    int maximumCount,
    string name);

[DllImport("kernel32",EntryPoint="WaitForSingleObject",
           SetLastError=true,CharSet=CharSet.Unicode)]
private static extern uint NT_WaitForSingleObject(
    uint hHandle,
    uint dwMilliseconds);

[DllImport("kernel32",EntryPoint="ReleaseSemaphore",
           SetLastError=true,CharSet=CharSet.Unicode)]
[return : MarshalAs( UnmanagedType.VariantBool )]
private static extern bool NT_ReleaseSemaphore(
    uint hHandle,
    int lReleaseCount,
    out int lpPreviousCount);

[DllImport("kernel32",EntryPoint="CloseHandle",
           SetLastError=true,CharSet=CharSet.Unicode)]
[return : MarshalAs( UnmanagedType.VariantBool )]
private static extern bool NT_CloseHandle(uint hHandle);

[DllImport("kernel32",EntryPoint="GetLastError",SetLastError=true)]
private static extern uint NT_GetLastError();

To see the application in action, download the demo project and run several instances of the application, say four. Click the "Create" button in each instance of the application to get a handle, or reference, to the semaphore. In each application then click the "Take" button to instruct each application that it should request access to the resource. Only the first application in which you clicked the "Take" button returns immediately with the message "Took the semaphore successfully." and the other instances all go into a waiting state. Now click the "Give" button in the application which owns the semaphore and the next application in the queue will immediately return from its waiting state with the message "Took the semaphore successfully." and so on in turn clicking the "Give" button in each application until each application has had ownership of the semaphore. When you're done, tell the operating system that you're done with the semaphore by closing the handle to it, click the "Destroy" button.

Conclusion

Share your resources well. Smile | :) (This article is dedicated to His Holiness, the 17th Gyalwa Karmapa, Trinley Thaye Dorje)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Robin Galloway-Lunn
Architect
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralYou r da man! Pinmembertataobr24-Oct-07 11:18 
GeneralSystem.Threading.Mutex PinmemberSau F Lee11-Jul-05 18:13 
GeneralC++ DLL PinmemberEd Hopkins18-Aug-04 7:07 
GeneraldoEvent() method Pinmembereafares2658-Nov-03 9:32 
GeneralRe: doEvent() method PinmemberRobin Galloway-Lunn8-Nov-03 11:06 
GeneralThanks! PinmemberAlvaro Mendez11-Aug-03 9:36 
GeneralRe: Thanks! PinmemberRobin Galloway-Lunn12-Aug-03 0:52 
GeneralRe: Thanks! PinmemberRobin Galloway-Lunn12-Aug-03 1:05 
GeneralProblem PinmemberJhon8-Oct-02 6:46 
GeneralRe: Problem PinmemberRobin Galloway-Lunn8-Oct-02 22:34 
GeneralRe: Problem PinmemberJhon9-Oct-02 10:05 
GeneralThreadpool PinmemberMarc Clifton1-Oct-02 11:25 
GeneralRe: Threadpool PinmemberRobin Galloway-Lunn1-Oct-02 22:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 1 Oct 2002
Article Copyright 2002 by Robin Galloway-Lunn
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid