Download no synchronisation example - 31 Kb
Download critical section example - 9 Kb
Download mutex example - 9 Kb
Download event object example - 9 Kb
Someone recently asked me what I recommend for synchronizing worker threads and I
suggested setting an event. This person's response was that you could not do that
since worker threads do not support a message pump (UI threads are required to support
messages). The confusion here is that events and messages are different animals
under windows.
I have forgotten where I originally copied these examples, but I found them to be
interesting because of their simplicity. If anyone is aware of the
author of this code, I would appreciate hearing from you, so I can give him/her
credit.
Note there is considerable support for threads in MFC that is not covered here.
API's like _beginthread (a C runtime library call) would likely be replaced by MFC
API's like AfxBeginThread in an MFC application.
No Synchronization
This first example illustrates two unsynchronized threads. The main loop, which
is the primary thread of a process, prints the contents of a global array of integers.
The thread called "Thread" continuously populates the global array of
integers.
#include <process.h>
#include <stdio.h>
int a[ 5 ];
void Thread( void* pParams )
{ int i, num = 0;
while ( 1 )
{
for ( i = 0; i < 5; i++ ) a[ i ] = num;
num++;
}
}
int main( void )
{
_beginthread( Thread, 0, NULL );
while( 1 )
printf("%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
return 0;
}
Note in this sample output, the numbers in red illustrate a state where the
primary thread preempted the secondary thread in the middle of populating the values of
the array:
81751652 81751652 81751651 81751651
81751651
81751652 81751652 81751651 81751651 81751651
83348630 83348630 83348630 83348629 83348629
83348630 83348630 83348630 83348629 83348629
83348630 83348630 83348630 83348629 83348629
If you are running Windows 9x/NT/2000, you can run this program by clicking
here. After the program begins to run, press the
"Pause" key stop the display output (this stops the primary thread's I/O, but
the secondary thread continues to run in the background) and any other key to restart it.
Critical Section Objects
What if your main thread needed all elements of the array to processed prior to
reading? One solution is to use a critical section.
Critical section objects provide synchronization similar to that provided by
mutex objects, except critical section objects can be used only by the threads of a
single process. Event, mutex, and semaphore objects can also be used in a single-process
application, but critical section objects provide a slightly faster, more efficient
mechanism for mutual-exclusion synchronization. Like a mutex object, a critical section
object can be owned by only one thread at a time, which makes it useful for protecting a
shared resource from simultaneous access. There is no guarantee about the order in which
threads will obtain ownership of the critical section, however, the system will be fair to
all threads.
#include <windows.h>
#include <process.h>
#include <stdio.h>
CRITICAL_SECTION cs;
int a[ 5 ];
void Thread( void* pParams )
{
int i, num = 0;
while ( TRUE )
{
EnterCriticalSection( &cs );
for ( i = 0; i < 5; i++ ) a[ i ] = num;
LeaveCriticalSection( &cs );
num++;
}
}
int main( void )<br>
{
InitializeCriticalSection( &cs );
_beginthread( Thread, 0, NULL );
while( TRUE )
{
EnterCriticalSection( &cs );
printf( "%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
LeaveCriticalSection( &cs );
}
return 0;
}
If you are running Windows 9x/NT/2000, you can run this program by clicking
here.
Mutex Objects
A mutex object is a synchronization object whose state is set to signaled when it is
not owned by any thread, and non-signaled when it is owned. Only one thread at a time can
own a mutex object, whose name comes from the fact that it is useful in coordinating
mutually exclusive access to a shared resource. For example, to prevent two threads from
writing to shared memory at the same time, each thread waits for ownership of a mutex
object before executing the code that accesses the memory. After writing to the shared
memory, the thread releases the mutex object.
Two or more processes can call CreateMutex to create the same named mutex. The
first process actually creates the mutex, and subsequent processes open a handle to the
existing mutex. This enables multiple processes to get handles of the same mutex, while
relieving the user of the responsibility of ensuring that the creating process is started
first. When using this technique, you should set the bInitialOwner flag to FALSE;
otherwise, it can be difficult to be certain which process has initial ownership.
Multiple processes can have handles of the same mutex object, enabling use of the
object for interprocess synchronization. The following object-sharing mechanisms are
available:
- A child process created by the
CreateProcess function can inherit a handle to a
mutex object if the lpMutexAttributes parameter of CreateMutex enabled
inheritance.
- A process can specify the mutex-object handle in a call to the
DuplicateHandle
function to create a duplicate handle that can be used by another process.
- A process can specify the name of a mutex object in a call to the
OpenMutex or CreateMutex function.
Generally speaking, if you are synchronizing threads within the same process, a
critical section object is more efficient.
#include <windows.h>
#include <process.h>
#include <stdio.h>
HANDLE hMutex;
int a[ 5 ];
void Thread( void* pParams )
{
int i, num = 0;
while ( TRUE )
{
WaitForSingleObject( hMutex, INFINITE );
for ( i = 0; i < 5; i++ ) a[ i ] = num;
ReleaseMutex( hMutex );
num++;
}
}
int main( void )
{
hMutex = CreateMutex( NULL, FALSE, NULL );
_beginthread( Thread, 0, NULL );
while( TRUE )<br>
{
WaitForSingleObject( hMutex, INFINITE );
printf( "%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
ReleaseMutex( hMutex );
}
return 0;
}
If you are running Windows 9x/NT/2000, you can run this program by clicking
here.
Event Objects
What if we want to force the secondary thread to run each time the primary thread
finishes printing the contents of the global array, so that the values in each line of
output is only incremented by one?
An event object is a synchronization object whose state can be explicitly set to
signaled by use of the SetEvent or PulseEvent function. Following are the
two types of event object.
| Object |
Description |
| Manual-reset event |
An event object whose state remains signaled until it is explicitly reset
to non-signaled by the ResetEvent function. While it is signaled, any number of
waiting threads, or threads that subsequently specify the same event object in one of the
wait functions, can be released. |
| Auto-reset event |
An event object whose state remains signaled until a single waiting thread
is released, at which time the system automatically sets the state to non-signaled. If no
threads are waiting, the event object's state remains signaled. |
The event object is useful in sending a signal to a thread indicating that a particular
event has occurred. For example, in overlapped input and output, the system sets a
specified event object to the signaled state when the overlapped operation has been
completed. A single thread can specify different event objects in several simultaneous
overlapped operations, then use one of the multiple-object wait functions to wait for the
state of any one of the event objects to be signaled.
A thread uses the CreateEvent function to create an event object. The creating
thread specifies the initial state of the object and whether it is a manual-reset or
auto-reset event object. The creating thread can also specify a name for the event object.
Threads in other processes can open a handle to an existing event object by specifying its
name in a call to the OpenEvent function. For additional information about names
for mutex, event, semaphore, and timer objects, see Interprocess Synchronization.
A thread can use the PulseEvent function to set the state of an event object to
signaled and then reset it to non-signaled after releasing the appropriate number of
waiting threads. For a manual-reset event object, all waiting threads are released. For an
auto-reset event object, the function releases only a single waiting thread, even if
multiple threads are waiting. If no threads are waiting, PulseEvent simply sets the
state of the event object to non-signaled and returns.
#include <windows.h>
#include <process.h>
#include <stdio.h>
HANDLE hEvent1, hEvent2;
int a[ 5 ];
void Thread( void* pParams )
{
int i, num = 0;
while ( TRUE )
{
WaitForSingleObject( hEvent2, INFINITE );
for ( i = 0; i < 5; i++ ) a[ i ] = num;
SetEvent( hEvent1 );
num++;
}
}
int main( void )
{
hEvent1 = CreateEvent( NULL, FALSE, TRUE, NULL );
hEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL );
_beginthread( Thread, 0, NULL );
while( TRUE )
{
WaitForSingleObject( hEvent1, INFINITE );
printf( "%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
SetEvent( hEvent2 );
}
return 0;
}
If you are running Windows 9x/NT/2000, you can run this program by clicking
here.
Summary of Synchronization Objects
The MSDN News for July/August 1998 has a front page article on Synchronization Objects.
The following table is from that article:
| Name |
Relative speed |
Cross process |
Resource counting |
Supported platforms |
| Critical Section |
Fast |
No |
No (exclusive access) |
9x/NT/CE |
| Mutex |
Slow |
Yes |
No (exclusive access) |
9x/NT/CE |
| Semaphore |
Slow |
Yes |
Automatic |
9x/NT |
| Event |
Slow |
Yes |
Yes |
9x/NT/CE |
| Metered Section |
Fast |
Yes |
Automatic |
9x/NT/CE |
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
About the Author
William T. Block
Web Developer
United States
Member
|
Bill's recent projects include graphical displays and printing of real-time data for the Oil Industry.
"I started programming Windows' applications right after the release of Windows 1.0 and I am now actively working with Microsoft .NET"
He currently works for Baker Hughes in the Houston, Texas area.
|
Add a reason or comment to your vote:
x
Votes of 3 or less require a comment
Comments and Discussions
|
|
 |
|
|
 |
|
 |
Brief and complete. Very good article
|
|
|
|
 |
|
|
 |
|
 |
good work.
|
|
|
|
 |
|
 |
Hi,
Does it work in linux system?
|
|
|
|
 |
|
 |
I just was wondering why you put for event1 intial value of TRUE and FALSE for event2 as the logic says you should reverse this values.
Fayez
|
|
|
|
 |
|
 |
Hi,
This is my first time I m using threads.Basic task i have to do is to run two functions(Extract & Thread)simultaneously.
Whatever i have done till now is:
I have created two functions
void CRestoreDlg::OnExtract()
{
// TODO: Add your control notification handler code here
Extract();
_beginthread( Thread, 0, NULL);
MessageBox("All the files are Extracted successfully");
}
void Thread(void* param)
{
CRestoreDlg *m_restore = new CRestoreDlg();
m_restore->m_Progress.SetRange(0,100);
for(int i = 0; i<100; i++)
{
m_restore->m_Progress.SetPos(i);
}
}
m_progress is a member variable of type CProgressCtrl
Problem: When i am running this code it is giving run time error
Debug Assertion Failed
please help me out in solving this
|
|
|
|
 |
|
 |
In my application I use Ten threads,in which 5 threads(writing threads) are writing to a excel file and five threads(reading threads) are reading from the excel file.
I have to synchronize the thread in such a way that when a thread writes to the file no other thread should access the excel file but when a thread reads from the excel file all other reading threads should be allowed to read the file but the writing threads should not be allowed to write to the file.
Can u help mr????????
abiiiiiiiii
abi
|
|
|
|
 |
|
 |
I am doing a realtime project.In that, i need 4 threads to be sychronized eachother one after the other.In that i am facing a probelm of buffer overwrite.
Senario:
I am using a 2D buffer [10][1000].Once i stored data into it, i signaled the second thread.The problem here is that the fisrt thread signal is missed by the second thread.Here the processing of the second thread is more that the first..
So if the first thread reaches the 3rd buffer the second buffer reach only the 2nd buffer.If it continues for sometime the data in the buffers got overwriten. So i need help to avoid this overwriten problem.
Reply me as soon as possible
|
|
|
|
 |
|
 |
Maybe my question seems fool because of my little experience, but why not call DeleteCriticalSection function to release the resources allocated for the critical section?
Thanks
-- modified at 22:16 Tuesday 27th June, 2006
|
|
|
|
 |
|
 |
I am attempting to use a named mutex to syncronize access to a shared resource between applications running for different users on the same machine.
I am using a name mutex "Global\MutexName" and am setting access privileges to everyone for the mutex.
The applicatons are reporting different mutex handles.
Should the handles be the same for named .net mutex objects residing in applications running for different users on the same machine?
Thanks in advance for your thoughts.
David Loeb
|
|
|
|
 |
|
 |
Thanx - Really Good Article
I suggest the following modification for a better illustration:
Replacing the following code fragment:
printf("%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
with the following
if( !
(a[0]==a[1] && a[0]==a[2] && a[0]==a[3] && a[0]==a[4])
&& (a[1]==a[2] && a[1]==a[3] && a[1]==a[4])
&& (a[2]==a[3] && a[2]==a[4])
&& (a[3]==a[4])
)
{ printf("Not synchronized\n"); }
For asynchronous threading
The output will be
Not synchronized
Not synchronized
Not synchronized
Not synchronized
Not synchronized
...
...
...
However, for synchronous threading you will got a blank screen
Osama E. Adly
|
|
|
|
 |
|
 |
This is a simple yet good intro for thread synchronization. However, I found most of your examples do not close the handles created upon exit .This will yield handle leaks I suppose?
Sonork 100.41263:Anthony_Yio
|
|
|
|
 |
 | vc++  |  | Anonymous | 1:35 19 Oct '03 |
|
|
 |
|
 |
Hi,
BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode );
|
|
|
|
 |
|
 |
from MSDN: _beginthread
You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.
_endthread automatically closes the thread handle (whereas _endthreadex does not). Therefore, when using _beginthread and _endthread, do not explicitly close the thread handle by calling the Win32 CloseHandle API. This behavior differs from the Win32 ExitThread API.
Larry Dobson
If you want to be seen, stand up.
If you want to be heard, speak up.
If you want to be respected, shut up.
William Batson
|
|
|
|
 |
|
 |
Exactly what I was looking for (instead of e.g. using SuspendThread/ResumeThread), short & informative.
PS: Perhaps the article would be better named 'Synchronizing in Multi-threaded Code'? I nearly skipped your great article because I didn't want to read another WinAPI "introduction" to threads.
PPS: What is a 'Metered Section'? Could you link the mentioned article?
|
|
|
|
 |
|
 |
You are right about the name of the article. RE: Metered Section, here is the definition from MSDN: "Metered sections are basically an extension of critical sections. Metered sections build upon critical sections in two important ways: They add the ability to synchronize threads across processes, and they provide resource counting semantics similar to the semaphore kernel object (thus the "metered" part of the name). So far the metered section may sound a lot like a semaphore, but it makes both of these extensions without sacrificing speed." "The idea behind metered sections was to develop a synchronization with the speed of a critical section and the cross-process resource counting of a semaphore. A secondary goal was to make them compatible with all Win32 platforms." "Learn from the mistakes of others. You can't live long enough to make them all yourself." Unknown
|
|
|
|
 |
|
 |
I am new To using thread in c++
could any one tell me i get
error C2065: '_beginthread' : undeclared identifier
when i try and compile the example on this article
#include
#include
int a[ 5 ];
void Thread( void* pParams )
{ int i, num = 0;
while ( 1 )
{
for ( i = 0; i < 5; i++ ) a[ i ] = num;
num++;
}
}
int main( void )
{
_beginthread( Thread, 0, NULL );
while( 1 )
printf("%d %d %d %d %d\n",
a[ 0 ], a[ 1 ], a[ 2 ],
a[ 3 ], a[ 4 ] );
return 0;
}
Any help would be great
|
|
|
|
 |
|
 |
Check about 4 threads down - You need to make sure that you have the correct library selected - either Multithreaded static or multithreaded dll
And they still ran faster and faster and faster, till they all just melted away, and there was nothing left but a great big pool of melted butter
"I ask candidates to create an object model of a chicken." -Bruce Eckel
|
|
|
|
 |
|
 |
Hi I am writing a program that generates x amount of numbers and adds them up.
It is a concurrent program and needs the adding part to be shared by 6 processes synchronised.Here is my code:
import java.io.*;
import Concurrency.*;
import java.lang.*;
public class RandomNumberCon extends PThread
{
public static Counter total_sum = new Counter();
public static void main(String args[])
{
RandomNumberCon program = new RandomNumberCon();
program.start();
}
}
class Counter
{
public int count;
Counter()
{
count=0;
}
public synchronized void increment()
{
count = count + 1;
}
public int getCount()
{
return count;
}
public void run()
{
Processor One = new Processor(1);
Processor Two = new Processor(2);
One.start();
Two.start();
try
{
Two.join();
One.join();
System.out.println(total_sum.getCount()+" is the current total");
}catch (Exception e) {}
}
}
class Processor extends PThread
{
private int thisnumber = 0;
public Processor(int number)
{
thisnumber=number ;
}
public void run()
{
int total = 0;
int input = getInt();
int array[] = new int[input];
while(input >= 0)
for(int b=0; b |
|
|
|
 |
|
 |
Hi,
This is VC++ community. But, you posted Java code.;P
|
|
|
|
 |
|
 |
I was wondering if anyone can help me!!! I need help writing a multi-threaded java program that creates 10 threads and waits until they finish to terminate(using join()). The main program will initialize an integer counter to 0 that each thread will access. The main program should then display the expected value in counter and the actual value in the counter.
If anyone can help....I would really appreciate it!!!!
|
|
|
|
 |
|
 |
I ran the CriticalSection program available from the article and it doesn't seem to work.
So I then copied and pasted the code used to make the CriticalSection exe into VC++ .NET, and when I compiled it and ran it, it didn't work the same way.
My question is, does CriticalSection work with WinXP using VC++ .NET? And if it doesn't, what must I use?
|
|
|
|
 |
|
 |
Absolutly should work in WinXP, but I cannot verify since I am running W2K.
I just created a new solution in VC++.NET and specified Win32 Application. In the Wizard I changed the application settings to specify a console application.
After exiting from the wizard, I changed the properties of the project under the C++ / Code Generation section to specify the multi-threaded libraries.
The project built and worked fine.
"Learn from the mistakes of others. You can't live long enough to make them all yourself." Unknown
|
|
|
|
 |
|
|
General
News
Suggestion
Question
Bug
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.