- Synchronisation question
- Posted by Hans on January 13th, 2004
Hello,
I want multiple threads to start doing something on the exact same time.
What should I use.
I know e.g. that with WaitForSingleObject one can only trigger one thread,
not more, so what function(s) are applicable here?
PS Since I have only one processor, I mean with 'the exact same moment' :
'first trigger thread1, and then thread2 etc, as shortly after one another
as possible'
Gr, Hans
- Posted by Kochkarev Sergey on January 13th, 2004
"Hans" <nomail@nodomain.invalid>
news:4003cab6$0$318$e4fe514c@news.xs4all.nl...
It depends on object. You could use mutex for your case.
- Posted by Emmanuel Viollet on January 13th, 2004
Kochkarev Sergey a écrit :
I'd rather use events.
See CreateEvent() for more information.
Mutexes will only allow for 1 thread synchronisation, whereas events
will allow you to synchronise multiple threads.
- Posted by Hans on January 13th, 2004
"Emmanuel Viollet" <Emmanuel.Viollet@webdyn.com> wrote in message
news:bu0nje$f5q$1@reader1.imaginet.fr...
Thanks
- Posted by Lucian Wischik on January 13th, 2004
"Hans" <nomail@nodomain.invalid> wrote:
I think you need to explain your problem more clearly.
Multiple threads *CAN'T* run at the same time, unless you have
hyperthreading or multiple CPUs. And even if you do, then they
probably won't be running at the same time if they access the same
bits of memory.
What notion of "observer" do you have who can observe whether or not
they're running at the same time? The answer to your original question
depends entirely on what this notional observer is. Any answer that's
been given to you without knowing what you're doing (or what your
notional observer is supposed to be) is at best misleading.
Setting an event, even a non-auto-reset event, will NOT normally set
two threads going at exactly the same time. It will either mark both
as runnable but leave them stalled, or it will mark one as runnable
and start running the other.
--
Lucian
- Posted by Cris Dunbar on January 13th, 2004
"Hans" <nomail@nodomain.invalid> wrote in message news:<4003cab6$0$318$e4fe514c@news.xs4all.nl>...
Use a manual reset event and then WFSO on it within each thread. Since
it's manual reset, every thread will see the signal. Depending on your
exact situation, you might want to look into PulseEvent, rather than
SetEvent. I've never used it, but I understand that it will signal
every thread that's _currently_ waiting, but then go ahead and reset
the event.
I don't immediately see how a mutex, as another poster suggested,
would be used for this problem.
Cris
- Posted by Gil Hamilton on January 13th, 2004
"Hans" <nomail@nodomain.invalid> wrote in message news:<4003cab6$0$318$e4fe514c@news.xs4all.nl>...
Many many ways to do that, but first, it's not correct that
WaitForSingleObject can only trigger one thread. It can trigger as
many threads as you arrange for it to trigger. When I read your
statement, it didn't sound right so I wrote the little program
included at the end of this message. Compile and try it on your
system. Both threads get awakened.
The only thing that you need to watch out for is that if you create
the event without the manual reset flag on (i.e. third arg to
CreateEvent set to FALSE), only one thread gets triggered because the
OS automatically resets the event after awakening only one thread
(that's a feature). If you use manual reset, you can just set it once
and every thread waiting on it will get awakened in one fell swoop.
Now to return to your question, there are any number of ways to have
two threads execute at approximately the same time. One way is to
create two events (both initialized to unsignaled), then at the point
where you wish to synchronize the two threads, have each execute:
SetEvent(EvX);
WaitForSingleObject(EvY);
where EvX and EvY are swapped between the two threads. Thus, each
thread will be within the space of approximately one system call of
each other, which is about the best you want to do (*). So, in thread
Y, you know that when your own call to WaitForSingleObject() returns,
thread X is at least on the tail end of the SetEvent call, and vice
versa.
(*) It occurs to me that if you don't care about being terribly
inconsiderate to all of the other threads on the machine, you can do
the same thing with a simple flag mechanism:
int EvX = 0;
int EvY = 0;
....
EvX = 1;
while (EvY == 0)
;
again swapping EvX and EvY in the other thread. Now when thread Y
breaks out of the while loop, it knows that thread X has at least
executed the EvN = 1 statement.
- GH
The program:
#include <windows.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
HANDLE ev;
DWORD WINAPI ThrFunc(void *myid)
{
int id = (int)myid;
printf("\nThread %d going to wait for event...");
WaitForSingleObject(ev, INFINITE);
printf("\nOK. Thread %d finished wait -- exiting\n");
return 0;
}
int main(int argc, char* argv[])
{
HANDLE thr[2];
ev = CreateEvent(NULL, TRUE, FALSE, NULL);
thr[0] = CreateThread(NULL, 0, ThrFunc, (void *)0, 0, NULL);
thr[1] = CreateThread(NULL, 0, ThrFunc, (void *)1, 0, NULL);
printf("\nSleeping to wait for my threads to be ready...");
Sleep(5000);
printf("\nOK, now going to single the event.\n");
SetEvent(ev);
printf("Waiting to harvest threads.\n");
WaitForMultipleObjects(2, thr, TRUE, INFINITE);
printf("WaitForMultipleObjects returned -- exiting\n");
return 0;
}