Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Q: use CreateThread() and TerminateThread() and message procedure

735 views
Skip to first unread message

JCR

unread,
Mar 26, 2002, 6:00:48 AM3/26/02
to
Hi all,

I use CreateThread() and TerminateThread() in a simple program.
Run/Stop the Thread works well, and the calling app. receives
feedback 'acknowledge' messages as well, so I know that the HWND
catched from the calling proc. is the right one.

Now, the problem here is that the app. doesn't receive MSG_FINISHED,
which is sent by the threaded procedure (fThreadProc) when it stops.
By the way, is it correct to do a call to TerminateThread()
from the inside of the threaded procedure itself ?

Below is a sample code that compiles to a DLL, loaded at startup
by the test app. that calls 'fRunThread()' when I click a button.
Why does my app receive MSG_STARTED and MSG_STOPPED
messages, but never receives the MSG_FINISHED message ?

TIA,
Jean-Christophe

// CODE START /////////////////////////////////////////////////////

//messages

#define MSG_ACK 101 //positive acknowledge
#define MSG_NACK 102 //negative acknowledge
#define MSG_STARTED 103 //thread started
#define MSG_STOPPED 104 //thread stopped (break)
#define MSG_FINISHED 105 //thread stopped (job complete)

// Global

HINSTANCE hDllInst = 0; //DLL instance
HWND hCallWnd = 0; //caller hwnd handler
HANDLE hThread = 0; //thread handle


//--------------------------------------------------------------
// Thread proc
//--------------------------------------------------------------
DWORD WINAPI fThreadProc( LPVOID lpParameter )
{
DWORD dw=500;

//dummy loop
while( --dw )
{ Sleep(10);
}

//auto stop
if(hThread)
TerminateThread(hThread,0);

if(hCallWnd)
SendMessage( hCallWnd, WM_COMMAND, MSG_FINISHED, 0 );

return 0;
}


//--------------------------------------------------------------
// Run thread
//--------------------------------------------------------------
WORD fRunThread()
{
LPTHREAD_START_ROUTINE lpThreadProc =
(LPTHREAD_START_ROUTINE)(fEquilThreadProc);
DWORD dwStack = 16 * 1024; //stack
LPVOID lpParam = NULL; //params
DWORD dwFlags = 0; //CREATE_SUSPENDED;//run thru DWORD
ResumeThread( HANDLE hThread );
DWORD dwThreadId = 0; //ID
LPDWORD lpThreadId = &dwThreadId; //*ID

//check
if(hThread)
return MSG_NACK;//thread already used

//create
hThread = CreateThread( NULL, dwStack, lpEquilThreadProc, lpParam,
dwFlags, lpThreadId );

if(!hThread)
return MSG_NACK;//oops

return MSG_STARTED;//ok
}


//--------------------------------------------------------------
// Stop calc thread
//--------------------------------------------------------------
WORD fStopEquilThread()
{
BOOL b = FALSE;

//check

if(!hThread)
return MSG_NACK;//no thread to stop

//stop

b = TerminateThread(hThread,1);

//chack
if(b==FALSE)
return MSG_NACK;//failed

hThread = 0;//reset

return MSG_STOPPED;//ok
}
// CODE ENDS //////////////////////////////////////////////////////////

Arnold Hendriks

unread,
Mar 26, 2002, 6:19:33 AM3/26/02
to
In comp.programming.threads JCR <Jean-Christo...@genebio.com> wrote:
> I use CreateThread() and TerminateThread() in a simple program.
Calls like TerminateThread are extremely disruptive and dangerous because
you could be killing a thread holding critical resources. Proper recovery
is almost impossible after a termination.

> Now, the problem here is that the app. doesn't receive MSG_FINISHED,
> which is sent by the threaded procedure (fThreadProc) when it stops.
> By the way, is it correct to do a call to TerminateThread()
> from the inside of the threaded procedure itself ?

How can your thread send a message when it has just committed suicide?

> DWORD WINAPI fThreadProc( LPVOID lpParameter )

...
> LPTHREAD_START_ROUTINE lpThreadProc =
> (LPTHREAD_START_ROUTINE)(fEquilThreadProc);
What is this 'fEquilThreadProc'? For my answer I just assumed you meant
fThreadProc. BTW: a cast like this shouldn't be necessary. Avoid a cast
whenever you can, because you might be hiding a problem with eg. calling
conventions and calling syntax with this.

--
Arnold Hendriks <a.hen...@b-lex.com>
B-Lex Information Technologies, http://www.b-lex.com/

Alexander Terekhov

unread,
Mar 26, 2002, 7:15:29 AM3/26/02
to
JCR wrote:
>
> Hi all,
>
> I use CreateThread() and TerminateThread() in a simple program.

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q254956

"Owned mutexes are considered abandoned but this can be detected. "

but associated shared data will be totally broken nevertheless.

"Other synchronization objects that the thread acquired are now
left unreleased. For example, critical sections that were entered
by the terminated thread are not released.

If the target thread was executing certain kernel32 calls when
it is terminated, the kernel32 state for the thread's process
could be inconsistent.

If the target thread is manipulating the global state of a
shared DLL, the state of the DLL could be inconsistent,
affecting other users of the DLL.

The stack memory that is used by the thread is lost and not
recovered until the process ends. A long-running process must
not do this because eventually all its address space will be used.
A few of these terminations a day over the course of a few months
will cause this problem. "

Yeah, and for "a short-running" process that's just OK! Idiotic.

"Because of all these issues with state leakage and corruption,
it is not a good idea to use the TerminateThread function. "

Hey MS-folks, but it was really "a good idea" to release such
brain-damaged thing! Really!! Thanks!!!

"The best approach to terminate threads gracefully is ...."

THIS:

http://sources.redhat.com/pthreads-win32

regards,
alexander.

Maxim S. Shatskih

unread,
Mar 26, 2002, 8:12:13 AM3/26/02
to
> By the way, is it correct to do a call to TerminateThread()
> from the inside of the threaded procedure itself ?

TerminateThread is a very bad function, and people from MS have un-recommend using it several times.
For instance, it causes the thread's user stack to go to leak.

Max

Maxim S. Shatskih

unread,
Mar 26, 2002, 8:42:15 AM3/26/02
to
> "The best approach to terminate threads gracefully is ...."
>
> THIS:
>
> http://sources.redhat.com/pthreads-win32

Do they use native NT or Win32 threads as a lower layer?
If not - then this is yet another "user mode threads" piece of crap.

Max

Arnold Hendriks

unread,
Mar 26, 2002, 9:32:22 AM3/26/02
to
In comp.programming.threads Maxim S. Shatskih <ma...@storagecraft.com> wrote:
>> "The best approach to terminate threads gracefully is ...."
>> THIS:
>> http://sources.redhat.com/pthreads-win32
> Do they use native NT or Win32 threads as a lower layer?
Native threads.

Tim Robinson

unread,
Mar 26, 2002, 9:43:11 AM3/26/02
to
"Arnold Hendriks" <a.hen...@b-lex.com> wrote in message
news:a7q0pm$qq2$1...@news.btcnet.nl...

| >> http://sources.redhat.com/pthreads-win32
| > Do they use native NT or Win32 threads as a lower layer?
| Native threads.

Do they use the native NT thread API or the Win32 thread API?

--
Tim Robinson
http://www.themoebius.org.uk/

Alexander Terekhov

unread,
Mar 26, 2002, 9:36:17 AM3/26/02
to

Why don't you just click on link and find it out yourself?

As for "piece of crap"... it is really hard to beat MS
stuff (APIs) in this respect (and THREADING especially).

regards,
alexander.

Pete Lee

unread,
Mar 26, 2002, 1:37:03 PM3/26/02
to
Alexander Terekhov <tere...@web.de> wrote in news:3CA06661.D8EBCF54
@web.de:

> Hey MS-folks, but it was really "a good idea" to release such
> brain-damaged thing! Really!! Thanks!!!
>
> "The best approach to terminate threads gracefully is ...."
>
> THIS:
>
> http://sources.redhat.com/pthreads-win32
>

I fail to see how pthreads-win32 prevents you from calling TerminateThread
on the underlying thread handle.

You may think the api is better. I disagree, but that is a seperate
discussion. Regardless of whether you use the win32 api's, the c-runtime
lib, or pthreads-win32, you will still have problems if you call
TerminateThread on a thread handle regardless of what you used to create
it.

So what exactly was your point ?

Maxim S. Shatskih

unread,
Mar 26, 2002, 3:25:54 PM3/26/02
to
> Do they use the native NT thread API or the Win32 thread API?

They are very, very similar, IIRC the main difference is that native NT thread API does not support user stack allocation, it must
be allocated separately.
kernel32!CreateThread calls BaseCreateStack, and only then ntdll!NtCreateThread.

Max

Maxim S. Shatskih

unread,
Mar 26, 2002, 3:27:36 PM3/26/02
to
> As for "piece of crap"... it is really hard to beat MS
> stuff (APIs) in this respect (and THREADING especially).

I personally consider Win32 threading and sync objects API as very good, except this ugly TerminateThread, which is known to be a
PITA to all serious Win32 developer.
This function seems to exist for things like debuggers, and not for production apps.

Max

Davlet Panech

unread,
Mar 26, 2002, 5:41:35 PM3/26/02
to
Pete Lee wrote:
>
> Alexander Terekhov <tere...@web.de> wrote in news:3CA06661.D8EBCF54
> @web.de:
> > Hey MS-folks, but it was really "a good idea" to release such
> > brain-damaged thing! Really!! Thanks!!!
> >
> > "The best approach to terminate threads gracefully is ...."
> >
> > THIS:
> >
> > http://sources.redhat.com/pthreads-win32
> >
>
> I fail to see how pthreads-win32 prevents you from calling TerminateThread
> on the underlying thread handle.
>
> You may think the api is better. I disagree, but that is a seperate
> discussion.

You can't be serious!

> Regardless of whether you use the win32 api's, the c-runtime
> lib, or pthreads-win32, you will still have problems if you call
> TerminateThread on a thread handle regardless of what you used to create
> it.
>
> So what exactly was your point ?

The point is, PTHREADS implement thread cancellation, Win32 doesn't,
which makes doing many things a major pain in the butt. With regards
to TerminateThread(), look at it this way: we have a function that
basically damages your process' execution environment, and therefore
should not be used under any circumstances -- why is it then supported?
It causes nothing but grief to those careless enough to use it! Is
that the API *you* prefer?

D.P.

Pete Lee

unread,
Mar 27, 2002, 1:23:12 AM3/27/02
to
>> You may think the api is better. I disagree, but that is a seperate
>> discussion.
> You can't be serious!

There are plenty of wrapper/helper thread classes out there that hide
some/all of the details of thread management, but no matter which one you
use, in all cases bad things will happen if you call TerminateThread
(pthreads included).

> The point is, PTHREADS implement thread cancellation, Win32 doesn't,
> which makes doing many things a major pain in the butt.

Ok, so it implements thread cancellation... so? 99.3235% of the 53238
thread wrappers (those are accurate numbers btw) on the net implement
cancellation. It's trivial to do.

> With regards
> to TerminateThread(), look at it this way: we have a function that
> basically damages your process' execution environment, and therefore
> should not be used under any circumstances -- why is it then
> supported?

Why speculate as to why it's supported? It really doesnt matter why, the
fact is it *IS* supported and so long as the function exists, newbs are
going to get in trouble if they use it regardless of whether they are using
a wrapper/helper class (like pthreads, CWinThread, threads++, ...) or pure
win32. So instead of screaming "USE PTHREADS" you should be saying "DONT
USE TERMINATETHREAD".

JCR

unread,
Mar 27, 2002, 4:45:59 AM3/27/02
to
Arnold Hendriks <a.hen...@b-lex.com> wrote in message news:<a7plg5$j70$1...@news.btcnet.nl>

> In comp.programming.threads JCR <Jean-Christo...@genebio.com> wrote:
> > I use CreateThread() and TerminateThread() in a simple program.
> > Now, the problem here is that the app. doesn't receive MSG_FINISHED,
> > which is sent by the threaded procedure (fThreadProc) when it stops.
> How can your thread send a message when it has just committed suicide?
Argh! Was so obvious that I didn't see, thanks to 'Arnold.H'.

Ok Guys, everything works well after suppression of TerminateThread!
The threaded procedure sends a message before ending, simple n'easy.
A case of runtime suicide (sigh) forwarded to alt.suicide.recovery

BTW, you were too hard with MS, which will proudly provide a definitive
replacement for TerminateThread(), named TerminateEverything().
So then you'll know that your thread IS done. Every thread, in fact.
JCR

Davlet Panech

unread,
Mar 27, 2002, 9:40:28 AM3/27/02
to
Pete Lee wrote:
>
> >> You may think the api is better. I disagree, but that is a seperate
> >> discussion.
> > You can't be serious!
>
> There are plenty of wrapper/helper thread classes out there that hide
> some/all of the details of thread management, but no matter which one you
> use, in all cases bad things will happen if you call TerminateThread
> (pthreads included).
>
> > The point is, PTHREADS implement thread cancellation, Win32 doesn't,
> > which makes doing many things a major pain in the butt.
>
> Ok, so it implements thread cancellation... so? 99.3235% of the 53238
> thread wrappers (those are accurate numbers btw) on the net implement
> cancellation. It's trivial to do.

"Trivial"? Hmm... The truth is it is impossible to support thread
cancellation
completely on Windows as some system have no non-blocking equivalents
(such
as CreateFile for openning an existing file on the "remote" filesystem
for
example). Not to mention things like COM, RPC, etc. But I see your point
--
until Windows provides built-in support for cancellation it can't be
correctly
emulated by any wrappers (pthreads included).

>
> > With regards
> > to TerminateThread(), look at it this way: we have a function that
> > basically damages your process' execution environment, and therefore
> > should not be used under any circumstances -- why is it then
> > supported?
>
> Why speculate as to why it's supported? It really doesnt matter why, the
> fact is it *IS* supported and so long as the function exists, newbs are
> going to get in trouble if they use it regardless of whether they are using
> a wrapper/helper class (like pthreads, CWinThread, threads++, ...) or pure
> win32. So instead of screaming "USE PTHREADS" you should be saying "DONT
> USE TERMINATETHREAD".

The question remains: how do you cancel a thread in Windows? Generally
speaking you can't ( even with the pthreads port ).

D.P.

Maxim S. Shatskih

unread,
Mar 27, 2002, 9:17:14 AM3/27/02
to
> The point is, PTHREADS implement thread cancellation, Win32 doesn't,
> which makes doing many things a major pain in the butt.

What is thread cancellation?
Is it the ability of sending a SIGINT-like signal to a thread, which will interrupt it, force it to execute some rundown code and
quit?

If yes - this is an extremely dangerous thing, at least as dangerous as TerminateThread.
For instance - let's imagine your thread have just allocated some memory or constructred some complex C++ object. Then this signal
arrives. Without lots of extra annoying bug-prone code, there are huge chances you will have a very complex memory and resource
leak.

The only bug-free way is that the thread can only quit itself and cannot be terminated.
Attempts to terminate the thread from outside must only be treated as "advice" by the thread, which can be delayed till some "good"
time or ignored.

NT kernel uses this for sure internally. The thread cannot be terminated while in kernel.
Terminate attempt will be scheduled for it, but the actual exit sequence will occur on next return from kernel to user. Kernel-only
threads in NT cannot be terminated at all - they can only quit themselves.

Usually, some "manual" solutions are used in Win32 to send this "advice" to the thread. This can be some shutdown event object, or
QueueUserApc or volatile global variable.

If you're not satisfied with it - write a C++ class for a thread which will encapsulate the shutdown event (or the shutdown flag) in
it.

> With regards
> to TerminateThread(), look at it this way: we have a function that
> basically damages your process' execution environment

Surely, this is a bad API. Never use it.

Max

Jerry Coffin

unread,
Mar 27, 2002, 10:15:20 AM3/27/02
to
In article <3CA1D9DC...@Tellabs.com>, Davlet...@Tellabs.com
says...

[ ... ]

> "Trivial"? Hmm... The truth is it is impossible to support thread
> cancellation completely on Windows as some system have no non-
> blocking equivalents (such as CreateFile for openning an existing
> file on the "remote" filesystem for example). Not to mention
> things like COM, RPC, etc. But I see your point -- until Windows
> provides built-in support for cancellation it can't be correctly
> emulated by any wrappers (pthreads included).

I think it should be pointed out that your use of "correct" above is
a bit misleading: there are some fairly clear differences between
POSIX threads and Win32 threads, and it's true that if you try to
support one on the other, it's impossible to do that entirely
correctly. That runs in both directions though: just as Win32
doesn't support cancellation "correctly", POSIX doesn't support
suspended threads (for only one example) "correctly".

In the end, while Win32 threads have some pitfalls to look out for,
after you know what you're doing, I believe it's a lot easier to make
good use of them than it is to make equally good use of pthreads.

From what I've seen, a _reasonably_ usable implementation of pthreads
on top of Win32 threads is _fairly_ easy to manage, while the reverse
seems to border on impossible.

--
Later,
Jerry.

The Universe is a figment of its own imagination.

Alexander Terekhov

unread,
Mar 27, 2002, 10:21:25 AM3/27/02
to

Pete Lee wrote:
[...]

> So instead of screaming "USE PTHREADS"
> you should be saying "DONT USE TERMINATETHREAD".

Okay, here we go:

DONT USE SUSPEND/RESUME
DONT USE EVENTS
DONT USE SEMAPHORES
DONT USE WAITFORMULTIPLESTUFF
DONT USE INTERLOCKEDSTUFF
DONT USE NON-SYNC-ACCESS (follow portable memory sync. rules)

Uhmm, other than simple mutexes and "I/O Completion Ports"
thread pooling, is there any MS-threading stuff I forgot
to "DONT USE IT"? The bottom line/general advice is:

USE PTHREADS... and (full 1,2,3,4,5 list):

http://groups.google.com/groups?as_umsgid=c29b5e33.0201240004.57d109f4%40posting.google.com

regards,
alexander.

Tim Robinson

unread,
Mar 27, 2002, 10:36:46 AM3/27/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CA1E375...@web.de...

| > So instead of screaming "USE PTHREADS"
| > you should be saying "DONT USE TERMINATETHREAD".
|
| Okay, here we go:
|
| DONT USE SUSPEND/RESUME
| DONT USE EVENTS
| DONT USE SEMAPHORES
| DONT USE WAITFORMULTIPLESTUFF
| DONT USE INTERLOCKEDSTUFF
| DONT USE NON-SYNC-ACCESS (follow portable memory sync. rules)

Why not?!

Maxim S. Shatskih

unread,
Mar 27, 2002, 10:52:17 AM3/27/02
to
> The question remains: how do you cancel a thread in Windows? Generally

What is the need in it at all? A dangerous thing at least.
BTW, COM and RPC are extremely useful things, much more useful then thread cancellation.

Max

Maxim S. Shatskih

unread,
Mar 27, 2002, 11:10:14 AM3/27/02
to
> Okay, here we go:
>
> DONT USE SUSPEND/RESUME

Agree. This is deadlock prone.

> DONT USE EVENTS

Why not? I see no reasons in not using events.
UNIX-style "condvars" are really atrocious compared to Win32/NT events.
As about NT kernel events - they are really great, since they can be created anywhere - even on stack - without bothering to
allocate them in some special way.
Linux kernel also has the "waitqueue" object which is nearly the same as NT's KEVENT.
Good ideas are reused in many implementations, you see.

> DONT USE SEMAPHORES

Why not? A convinient object sometimes.

> DONT USE WAITFORMULTIPLESTUFF

Again why not?

> DONT USE INTERLOCKEDSTUFF

Again why not? Sometimes it is convinient, especially in the kernel.

> thread pooling, is there any MS-threading stuff I forgot
> to "DONT USE IT"? The bottom line/general advice is:

Sorry, I'm free from MSphobic biases, thus I cannot understand your advices.
:-)

Max

Alexander Terekhov

unread,
Mar 27, 2002, 12:42:30 PM3/27/02
to

"Maxim S. Shatskih" wrote:
>
> > Okay, here we go:
> >
> > DONT USE SUSPEND/RESUME
>
> Agree. This is deadlock prone.
>
> > DONT USE EVENTS
>
> Why not?

Because this is race-condition prone, to begin with.

> I see no reasons in not using events.
> UNIX-style "condvars" are really atrocious compared to Win32/NT events.

You better learn how to use them first, before making such statements.
See No "1." in the "1,2,3,4,5" list.

> As about NT kernel events - they are really great,

I don't really care much about "kernel" internal stuff, however:

> since they can be created anywhere - even on stack - without bothering to
> allocate them in some special way.
> Linux kernel also has the "waitqueue" object which is nearly the same as NT's KEVENT.

http://users.footprints.net/~kaz/lmc.html

"Home of LMC

LMC stands for Linux Mutexes and Conditions. It is a small C
header file and source file which implements these mutual
exclusion and synchronization primitives to be used in
Linux kernel programming. It comes with a brief white
paper that explains why these things are useful, and how
they are used. ..."

> Good ideas are reused in many implementations, you see.
>
> > DONT USE SEMAPHORES
>
> Why not? A convinient object sometimes.

Again, study condvars... you'll see it then.

> > DONT USE WAITFORMULTIPLESTUFF
>
> Again why not?

See above.

> > DONT USE INTERLOCKEDSTUFF
>
> Again why not? Sometimes it is convinient, especially in the kernel.

Memory synchronization, busy-waiting, etc..

> > thread pooling, is there any MS-threading stuff I forgot
> > to "DONT USE IT"? The bottom line/general advice is:
>
> Sorry, I'm free from MSphobic biases, thus I cannot understand your advices.
> :-)

How can I help you ("MSphobic biases" aside)?

regards,
alexander.

Alexander Terekhov

unread,
Mar 27, 2002, 2:56:40 PM3/27/02
to

"Maxim S. Shatskih" wrote:
>
> > The point is, PTHREADS implement thread cancellation, Win32 doesn't,
> > which makes doing many things a major pain in the butt.
>
> What is thread cancellation?
[...async.cancel is dangerous/bad...]

In addition to "1." from the 1..5 list (I mean
http://www.awl.com/cseng/titles/0-201-63392-2/ ),
you might want to take a look at this discussion:

http://groups.google.com/groups?threadm=3C7BD6B3.1EAE29D0%40web.de

regards,
alexander.

Jerry Coffin

unread,
Mar 27, 2002, 4:29:47 PM3/27/02
to
In article <3CA20486...@web.de>, tere...@web.de says...

[ ... ]

> > > DONT USE EVENTS
> >
> > Why not?
>
> Because this is race-condition prone, to begin with.

IOW, _you've_ never learned to use them properly, so you assume
nobody else has either.

Events aren't particularly prone to race conditions -- in fact, as
long as you have a reasonable clue of what you're doing, they work
quite nicely.

Pete Lee

unread,
Mar 27, 2002, 4:42:08 PM3/27/02
to
> DONT USE SUSPEND/RESUME
> DONT USE EVENTS
> DONT USE SEMAPHORES
> DONT USE WAITFORMULTIPLESTUFF
> DONT USE INTERLOCKEDSTUFF
> DONT USE NON-SYNC-ACCESS (follow portable memory sync. rules)
>
> Uhmm, other than simple mutexes and "I/O Completion Ports"
> thread pooling, is there any MS-threading stuff I forgot
> to "DONT USE IT"? The bottom line/general advice is:
>
> USE PTHREADS... and (full 1,2,3,4,5 list):

You do realize that pthreads uses those things you say "DONT USE" ? It
uses SuspendThread, ResumeThread, CreateEvent, CreateSemaphore,
WaitForMultipleObjects, WaitForSingleObject, InterlockedIncrement, and
InterlockedDecrement. I still have no idea what your point is other that
you seem to be fanatical about using pthreads.

Alexander Terekhov

unread,
Mar 27, 2002, 5:16:18 PM3/27/02
to

Jerry Coffin wrote:
>
> In article <3CA20486...@web.de>, tere...@web.de says...
>
> [ ... ]
>
> > > > DONT USE EVENTS
> > >
> > > Why not?
> >
> > Because this is race-condition prone, to begin with.
>
> IOW, _you've_ never learned to use them properly, so you assume
> nobody else has either.

No, I do NOT "assume nobody else has either". However, I do
assume that anyone else who really did his homework 100% and
really "learned to use them properly" should have definitely
come to the conclusion "DONT USE EVENTS"... on the 2nd minute
of his subsequent *condvar study*.

> Events aren't particularly prone to race conditions -- in fact, as
> long as you have a reasonable clue of what you're doing, they work
> quite nicely.

How about MSDN authors/reviewers/support folks? Do they
"have a reasonable clue of what you're doing"? No, they
DON'T:

http://groups.google.com/groups?as_umsgid=c29b5e33.0201240132.3d78369f%40posting.google.com

And, I am sorry, but given your rather silly
response I think that you DON'T have it too,
Jerry.

regards,
alexander.

Alexander Terekhov

unread,
Mar 27, 2002, 5:38:10 PM3/27/02
to

Pete Lee wrote:
>
> > DONT USE SUSPEND/RESUME
> > DONT USE EVENTS
> > DONT USE SEMAPHORES
> > DONT USE WAITFORMULTIPLESTUFF
> > DONT USE INTERLOCKEDSTUFF
> > DONT USE NON-SYNC-ACCESS (follow portable memory sync. rules)
> >
> > Uhmm, other than simple mutexes and "I/O Completion Ports"
> > thread pooling, is there any MS-threading stuff I forgot
> > to "DONT USE IT"? The bottom line/general advice is:
> >
> > USE PTHREADS... and (full 1,2,3,4,5 list):
>
> You do realize that pthreads uses those things you say "DONT USE" ? It
> uses SuspendThread, ResumeThread, CreateEvent, CreateSemaphore,
> WaitForMultipleObjects, WaitForSingleObject, InterlockedIncrement, and
> InterlockedDecrement.

Yes, I do realize it. That's the IMPLEMENTATION/INTERNAL stuff, stupid.

What else should it use on brain-damaged Win32 as a client?

Of course, it would be nice/great to have MS-made
fully compliant POSIX/SUS (95/98/01) *subsystem*
(threads included):

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwbgen/html/msdn_posix.asp

Hey, and why don't you tell it to your Microsoft account rep?

> I still have no idea what your point is other that
> you seem to be fanatical about using pthreads.

I am fanatical about good/reasonable/simple/well-defined
programming interfaces/models. Win32-threading isn't such
one. Pthreads IS pretty close to such "ideal"! ;-)

regards,
alexander.

Jerry Coffin

unread,
Mar 27, 2002, 5:55:33 PM3/27/02
to
In article <3CA244B2...@web.de>, tere...@web.de says...

[ ... ]

> No, I do NOT "assume nobody else has either". However, I do
> assume that anyone else who really did his homework 100% and
> really "learned to use them properly" should have definitely
> come to the conclusion "DONT USE EVENTS"... on the 2nd minute
> of his subsequent *condvar study*.

Nonsense.



> > Events aren't particularly prone to race conditions -- in fact, as
> > long as you have a reasonable clue of what you're doing, they work
> > quite nicely.
>
> How about MSDN authors/reviewers/support folks? Do they
> "have a reasonable clue of what you're doing"? No, they
> DON'T:
>
> http://groups.google.com/groups?as_umsgid=c29b5e33.0201240132.3d78369f%40posting.google.com
>
> And, I am sorry, but given your rather silly
> response I think that you DON'T have it too,

Let's see here: you try to prove your statement by referring me to
another message you wrote? And you have the nerve to call anybody
else on earth "silly"? You really are a piece of work Alexander!

In that message, you get even worse: you posted something to some
_Redhat_ server, and you're waiting for some "official" reply --
which, of course, isn't going to happen since the chances of anybody
from MS ever even _reading_ it are almost nil.

Dragan Cvetkovic

unread,
Mar 27, 2002, 5:58:21 PM3/27/02
to
Jerry Coffin <jco...@taeus.com> writes:
> >
> > http://groups.google.com/groups?as_umsgid=c29b5e33.0201240132.3d78369f%40posting.google.com
> >
> > And, I am sorry, but given your rather silly
> > response I think that you DON'T have it too,
>
> Let's see here: you try to prove your statement by referring me to
> another message you wrote? And you have the nerve to call anybody
> else on earth "silly"? You really are a piece of work Alexander!
>
> In that message, you get even worse: you posted something to some
> _Redhat_ server, and you're waiting for some "official" reply --
> which, of course, isn't going to happen since the chances of anybody
> from MS ever even _reading_ it are almost nil.
>

Well, in that message he posts a letter that he has sent to
ms...@microsoft.com previously and for which he hasn't received a
response. What's wrong with it?

Bye, Dragan


--
Dragan Cvetkovic,

To be or not to be is true. G. Boole

Alexander Terekhov

unread,
Mar 27, 2002, 6:40:03 PM3/27/02
to

Uhhmm, I would say that below is a good example
demonstrating "deep" analysis skills of an average
Win32 programmer out there (and their ability to
click on links/read/try-to-understand BEFORE
opening their mouth/producing lines of code/etc).

;-)

Oh, Ah, and I have NO comments, Jerry.

regards,
alexander.

Maxim S. Shatskih

unread,
Mar 27, 2002, 4:10:15 PM3/27/02
to
> > > DONT USE EVENTS
> >
> > Why not?
>
> Because this is race-condition prone, to begin with.

Only if one has "twisted hands".
Any serious development even in Win32 (not to say NT kernel) requires good understanding of what is going on in terms of parallelism
and races. It is better to never code any races then to debug them :-)
Without such an understanding, do not go in for MT programming - regardless of whether this is Win32 or pthreads.

> You better learn how to use them first, before making such statements.

Thanks. I have heard of them from one UNIX guy, a terrifying inconvinient thing.
sleep()/wakeup() is another outdated stuff - even modern UNIXen try to not use them - Linux uses waitqueue which is nearly the same
as NT event.
I prefer NT-style events.

> See No "1." in the "1,2,3,4,5" list.

Oh yes, posing yourself as guru and pointing to the self-promoting article is a very good idea.

> > As about NT kernel events - they are really great,
>
> I don't really care much about "kernel" internal stuff, however:

So why you crosspost to NT kernel newsgroup?

> > Linux kernel also has the "waitqueue" object which is nearly the same as NT's KEVENT.
>
> http://users.footprints.net/~kaz/lmc.html
>
> "Home of LMC
>
> LMC stands for Linux Mutexes and Conditions.

A red herring.
I was speaking on _events in Linux kernel_, not on some LMC.

> > > DONT USE WAITFORMULTIPLESTUFF
> >
> > Again why not?
>
> See above.

Sorry, I prefer multiple waits :-) though yes, they are rarely needed.
In fact, Linux uses this semantics _only_ for select()/poll() - without bothering to encapsulate the dispatcher properly. :-)

> > > DONT USE INTERLOCKEDSTUFF
> >
> > Again why not? Sometimes it is convinient, especially in the kernel.
>
> Memory synchronization

Automatic on interlocked operations.

>, busy-waiting

The person must be sane enough to understand whether he wants to busy wait or not.
For instance, interlocked list operations are very useful, since they do not require any mutex or spinlock acquisition.

> How can I help you ("MSphobic biases" aside)?

Sorry, you cannot help me :-)

Max

Maxim S. Shatskih

unread,
Mar 27, 2002, 7:37:23 PM3/27/02
to
> > I still have no idea what your point is other that
> > you seem to be fanatical about using pthreads.
>
> I am fanatical about good/reasonable/simple/well-defined
> programming interfaces/models. Win32-threading isn't such
> one.

Usually, such claims must be proven, and not by pointing to self-glorifying texts on the web.

From the whole this thread, I cannot conclude anything on pthreads, I can only confirm my conclusion on usual Linuxoids :-)
Their usual behaviour is - "MS sux! sux! SUX! and I'm great! great! GREAT!" - usually without any real arguments.

Max

Alexander Terekhov

unread,
Mar 27, 2002, 8:05:51 PM3/27/02
to
> > How can I help you ("MSphobic biases" aside)?
>
> Sorry, you cannot help me :-)

Yes, now I see it. Forget it and "enjoy" Win32.

regards,
alexander.

Maxim S. Shatskih

unread,
Mar 27, 2002, 8:50:53 PM3/27/02
to
> Yes, now I see it. Forget it and "enjoy" Win32.

Sorry, this_coding_style_alone (used by pthreads) is enough for me to prefer Win32.
I hate press "_" extra time
:-))))

I also have strong dislike to using any sources scattered all over the web and poorly documented in any serious projects.
Surely the native OS capabilities are more trustworthy, not to say the legal reasons - can I use GPLed code in commercial software?
I also hate stupid wrappers - and "pthreads over Win32" seems to be a stupid wrapper over native Win32 threading. There is an
"Occam's Razor" principle.

Maybe "pthreads over Win32" can be useful to write the code which must be portable between Win32 and UNIXen - but for now I have no
such projects.

Win32 has its drawbacks (USER, for instance), but they are not in threading.

Max

Patrick TJ McPhee

unread,
Mar 27, 2002, 8:50:52 PM3/27/02
to
In article <MPG.170b8ff43...@news.direcpc.com>,
Jerry Coffin <jco...@taeus.com> wrote:

% doesn't support cancellation "correctly", POSIX doesn't support
% suspended threads (for only one example) "correctly".

But suspending a thread is roughly equivalent to asynchronously terminating
a thread when it comes to introducing instability.
--

Patrick TJ McPhee
East York Canada
pt...@interlog.com

Patrick TJ McPhee

unread,
Mar 27, 2002, 9:14:11 PM3/27/02
to
[note the follow-ups are set to comp.programming.threads]


In article <a7tnra$ic0$1...@gavrilo.mtu.ru>,
Maxim S. Shatskih <ma...@storagecraft.com> wrote:

[about condition variables]

% Thanks. I have heard of them from one UNIX guy, a terrifying inconvinient
% thing.

That's an odd statement. CVs are a fairly light-weight signalling
mechanism. They're not semaphores, so they're not the right thing to
use if you need a semaphore, but if you want to wait for some arbitrary
condition to become true, they're really quite convenient.

Alexander Terekhov

unread,
Mar 27, 2002, 9:19:28 PM3/27/02
to
"Maxim S. Shatskih" wrote:
>
> > > I still have no idea what your point is other that
> > > you seem to be fanatical about using pthreads.
> >
> > I am fanatical about good/reasonable/simple/well-defined
> > programming interfaces/models. Win32-threading isn't such
> > one.
>
> Usually, such claims must be proven, and not by pointing to self-glorifying texts on the web.

Heck! Such claims aside for a moment, could you
please define "self-glorifying texts on the web"
term for me-stupid?

> From the whole this thread, I cannot conclude anything on pthreads,

You are not supposed to "conclude anything on pthreads"
from this thread. Go and learn them, use google and
its archives (this c.p.t newsgroup, I mean), etc. Do
your own research. Think... or just stay in the total
ignorance of something NOT so ugly as Win32-threading
model and its APIs. That's all your choice.

> I can only confirm my conclusion on usual Linuxoids :-)
> Their usual behaviour is - "MS sux! sux! SUX! and I'm
> great! great! GREAT!" - usually without any real arguments.

Okay, for the record, here is one more "MS sux! sux! SUX!
and I'm great! great! GREAT!" link:

http://www.codeproject.com/interview/herbsutter3032002.asp?forumid=3455&tid=131105&select=133959#xx133959xx
(see the whole "Re:LOL" sub-thread)

but... I guess that most likely (given the "abilities"
you have demonstrated so far in this silly thread), you
won't be able to find "any real arguments" there too. ;-)

regards,
alexander.

Alexander Terekhov

unread,
Mar 27, 2002, 9:47:43 PM3/27/02
to

"Maxim S. Shatskih" wrote:
[...]

> Surely the native OS capabilities are more trustworthy,
> not to say the legal reasons - can I use GPLed code in
> commercial software?

Ever heard of *L*GPL (GNU *Lesser* General Public License)?

[...]


> Maybe "pthreads over Win32" can be useful to write the
> code which must be portable between Win32 and UNIXen

http://sources.redhat.com/pthreads-win32
(see "COPYING" in CVS)

"Although pthreads-win32 makes it possible for applications
that use POSIX threads to be ported to Win32 platforms, the
broader goal of the project is to encourage the use of open
standards, and in particular, to make it just a little easier
for developers writing Win32 applications to consider
widening the potential market for their products"

regards,
alexander.

Patrick TJ McPhee

unread,
Mar 27, 2002, 9:48:38 PM3/27/02
to
[note follow-up to comp.programming.threads]

In article <a7sn0m$2jpp$1...@gavrilo.mtu.ru>,


Maxim S. Shatskih <ma...@storagecraft.com> wrote:

% What is thread cancellation?
% Is it the ability of sending a SIGINT-like signal to a thread, which
% will interrupt it, force it to execute some rundown code and
% quit?
%
% If yes - this is an extremely dangerous thing, at least as dangerous as
% TerminateThread.

Cancellation is TerminateThread designed properly. The programmer can
choose whether a thread accepts cancellation requests or not, and whether
they should be acted on immediately (asynchronous cancellation) or at
one of a well-defined set of function calls (deferred cancellation).
If I've understood this thread correctly, asynchronous thread cancellation
is slightly less dangerous than TerminateThread, and should only be
enabled for highly CPU-intensive threads which don't allocate any
resources. Deferred threads provide a reliable clean-up mechanism so
that a cancelled thread _can_ be guaranteed not to have any resource
leaks.

Posix deferred cancellation is essentially advice to the target thread
to go away and stop bothering people, along with a mechanism to
interrupt system calls so the target thread can take that advice
promptly. I'm not sure that it requires kernel support, but it
does need the C library to check for the cancellation request at
the appropriate moments.

% If you're not satisfied with it - write a C++ class for a thread which
% will encapsulate the shutdown event (or the shutdown flag) in
% it.

Very much in the posix spirit.

Alexander Terekhov

unread,
Mar 27, 2002, 10:33:58 PM3/27/02
to

Patrick TJ McPhee wrote:
>
> [note follow-up to comp.programming.threads]
>
> In article <a7sn0m$2jpp$1...@gavrilo.mtu.ru>,
> Maxim S. Shatskih <ma...@storagecraft.com> wrote:
>
> % What is thread cancellation?
> % Is it the ability of sending a SIGINT-like signal to a thread, which
> % will interrupt it, force it to execute some rundown code and
> % quit?
> %
> % If yes - this is an extremely dangerous thing, at least as dangerous as
> % TerminateThread.
>
> Cancellation is TerminateThread designed properly. The programmer can
> choose whether a thread accepts cancellation requests or not, and whether
> they should be acted on immediately (asynchronous cancellation) or at
> one of a well-defined set of function calls (deferred cancellation).
> If I've understood this thread correctly, asynchronous thread cancellation
> is slightly less dangerous than TerminateThread, and should only be
> enabled for highly CPU-intensive threads which don't allocate any
> resources.

and/or modify some shared data and/or do something else
which isn't *async-cancel-safe*. Such async-cancel-regions
are formed using pthread_setcanceltype() call. Another
pthread call -- pthread_setcancelstate() is used to
control cancelability too: ENABLED/DISABLED (enabled
is the default). In C++, cancel (and thread exit) is
just an exception causing C++ stack-unwinding raised
by cancel.points or from async-cancel-regions (at any
point inside them).

regards,
alexander.

Maxim S. Shatskih

unread,
Mar 28, 2002, 3:26:34 AM3/28/02
to
> resources. Deferred threads provide a reliable clean-up mechanism so
> that a cancelled thread _can_ be guaranteed not to have any resource
> leaks.

Rundown routines are reliable only on paper, coding such things are extremely bug-prone.

> interrupt system calls so the target thread can take that advice
> promptly. I'm not sure that it requires kernel support, but it

Interrupting syscalls requires the kernel support for sure, and NT kernel does support it (FILE_SYNCHRONOUS_IO_ALERT and such),
though IIRC Win32 does not.

Max

Alexander Terekhov

unread,
Mar 28, 2002, 7:19:27 AM3/28/02
to

"Maxim S. Shatskih" wrote:
>
> > resources. Deferred threads provide a reliable clean-up mechanism so
> > that a cancelled thread _can_ be guaranteed not to have any resource
> > leaks.
>
> Rundown routines are reliable only on paper, coding such things are extremely bug-prone.

Ever heard of *exception-safety*, Maxim?

Here is a couple of links (to papers
on "reliability/exceptions")) for you:

http://www.bleading-edge.com/Publications/C++Report/v9603/Article2a.htm
http://www.bleading-edge.com/Publications/C++Report/v9605/Column1.htm
http://www.bleading-edge.com/Publications/C++Report/v9607/Column2.htm
http://www.boost.org/more/generic_exception_safety.html
http://www.gotw.ca

And, please, keep your mouth closed until at least
you've done with that basic stuff for the "modern"
programmers.

regards,
alexander.

P.S. Given your "mtu.ru" server address
(organization used to be full of *clever*
and *committed* people (NOT dilettantes/
amateurs) a couple of years ago, at least)
and your "kernel" programming interests,
I'm going to recommend to you AGAIN that
you better click on the 2nd link below:

http://groups.google.com/groups?as_umsgid=3CA20486.867A6B3E%40web.de

"> As about NT kernel events - they are really great,

I don't really care much about "kernel" internal stuff, however:

> since they can be created anywhere - even on stack - without


bothering to
> allocate them in some special way.

> Linux kernel also has the "waitqueue" object which is nearly the same
as NT's KEVENT.

http://users.footprints.net/~kaz/lmc.html

"Home of LMC

LMC stands for Linux Mutexes and Conditions. It is a small C

header file and source file which implements these mutual
exclusion and synchronization primitives to be used in
Linux kernel programming. It comes with a brief white
paper that explains why these things are useful, and how
they are used. ...""

AND *READ* THAT BRIEF PAPER WRITTEN BY KAZ, HECK!

Jos Scherders

unread,
Mar 28, 2002, 4:23:35 PM3/28/02
to
> From the whole this thread, I cannot conclude anything on pthreads, I can
only confirm my conclusion on usual Linuxoids :-)
> Their usual behaviour is - "MS sux! sux! SUX! and I'm great! great!
GREAT!" - usually without any real arguments.
>
> Max

Agreeing with Max. Can't we ban this guys from this list. I am fed up with
this pointless discussion. Uh, what discussion ? I haven't seen one decent
argument in favor of anything, including pthreads.

Jos.

Alexander Terekhov

unread,
Mar 28, 2002, 5:36:52 PM3/28/02
to

Jos Scherders wrote:
>
> > From the whole this thread, I cannot conclude anything on pthreads, I can
> only confirm my conclusion on usual Linuxoids :-)
> > Their usual behaviour is - "MS sux! sux! SUX! and I'm great! great!
> GREAT!" - usually without any real arguments.
> >
> > Max
>
> Agreeing with Max. Can't we ban this guys from this list.

http://www.faqs.org/faqs/usenet/moderated-ng-faq/index.html

> I am fed up with
> this pointless discussion. Uh, what discussion ? I haven't seen one decent
> argument in favor of anything, including pthreads.

http://groups.google.com/groups?group=sci.med.vision

regards,
alexander.

Jonathan de Boyne Pollard

unread,
Mar 27, 2002, 4:19:26 PM3/27/02
to
AT> "The best approach to terminate threads gracefully is ...."
AT> THIS:
AT> http://sources.redhat.com/pthreads-win32

However, its condition variable implementation should be avoided if one
can guarantee that one is using Windows NT and not DOS-Windows.

Alexander Terekhov

unread,
Mar 30, 2002, 10:12:41 AM3/30/02
to

Uhmm. Interesting. Could you please elaborate?

regards,
alexander.

Jonathan de Boyne Pollard

unread,
May 12, 2002, 3:19:25 PM5/12/02
to
AT> "The best approach to terminate threads gracefully is ...."
AT> THIS:
AT> http://sources.redhat.com/pthreads-win32

JdeBP> However, its condition variable implementation should be avoided if one
JdeBP> can guarantee that one is using Windows NT and not DOS-Windows.

AT> Uhmm. Interesting. Could you please elaborate?

If one can guarantee that one is using Windows NT and not DOS-Windows,
then many design constraints on a Win32 program disappear. Most notably
in this particular case, the principal (and pretty much only) reason for
not having a simple condition variable implementation, the lack of
SignalObjectAndWait() on DOS-Windows, goes away.

josh

unread,
May 12, 2002, 5:40:10 PM5/12/02
to
Perhaps I'm misunderstanding the topic, but isn't the very concept of a thread
lacking on "Dos-Windows", and therefore this platform should simply be excluded
from the argument?

Gary Chanson

unread,
May 12, 2002, 11:50:47 PM5/12/02
to

"josh" <jo...@xtreme.net> wrote in message
news:1106_1021239610@adgq423gadgqdge...

> Perhaps I'm misunderstanding the topic, but isn't the very concept of a
thread
> lacking on "Dos-Windows", and therefore this platform should simply be
excluded
> from the argument?

I assume that by "Dos-Windows" he means Win9x not Win30. Win9x does
have threads but does not support SignalObjectAndWait().

--

-Gary Chanson (MVP for Windows SDK)
-gch...@TheWorld.com

-War is the last resort of the incompetent.


Alexander Terekhov

unread,
May 13, 2002, 3:15:03 AM5/13/02
to

Jonathan de Boyne Pollard wrote:
>

SignalObjectAndWait() != POSIX condition variable,
to begin with... and, BTW, given:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q173260
("PRB: Synchronization Failure When Debugging (Q173260)")

that "entire" stuff is just yet another illustration
of "total brain-damage" principle that rules at MS
location...

regards,
alexander.

P.S. < quote from the link/PRB above >

"....
RESOLUTION

Placing Sleep(0) before the PulseEvent() or
SetEvent()/ResetEvent() calls will probably"

'probably' He he. ;-)

"avoid this problem, but this is not guaranteed
either. "

Ahhh. ;-) ;-)

"Unfortunately, there is no guaranteed workaround
for this situation.
...."

That's NOT true. There IS *pretty guaranteed* ;-)
"workaround for this situation":

http://sources.redhat.com/pthreads-win32

Jonathan de Boyne Pollard

unread,
May 13, 2002, 3:54:01 AM5/13/02
to
j> [...] isn't the very concept of a thread lacking on "Dos-Windows",
j> and therefore this platform should simply be excluded from the
j> argument?

No. DOS-Windows has had threads since DOS-Windows 95.

josh

unread,
May 13, 2002, 4:58:23 AM5/13/02
to
Oh, I see. I guess I didn't consider 95 a "DOS" anything.

Slava M. Usov

unread,
May 13, 2002, 10:12:54 AM5/13/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CDF67F7...@web.de...

[...]

> http://support.microsoft.com/default.aspx?scid=kb;EN-US;q173260
> ("PRB: Synchronization Failure When Debugging (Q173260)")
>
> that "entire" stuff is just yet another illustration
> of "total brain-damage" principle that rules at MS
> location...

Did you read the article by keywords, such as "probably" and "no guaranteed
workaround", skipping the contents completely? If you did not notice, the
article says that while a thread is suspended, PulseEvent() will not wake
the thread, which is the intended and documented behavior:

[quoting Platform SDK]

[...] if no thread can be released immediately, PulseEvent simply sets the
event object's state to nonsignaled and returns.

[end quote]

Now how is that different from the KB article? The bottom line, PulseEvent()
works as it is advertised; that debugging is difficult is irrelevant.

S

Lucian Wischik

unread,
May 13, 2002, 11:08:20 AM5/13/02
to
[pthreads]

I love the way Windows uses events rather than condition variables! The
fact that a "Signal" on an event isn't lost even though no-one's waiting
on it (while a condition variable signal does get lost) means you don't
have to wrap your brain around that horrendous
release-mutex-then-wait-then-reacquire-mutex command. Windows signals seem
way more natural.

--
Lucian Wischik, Queens' College, Cambridge CB3 9ET. www.wischik.com/lu

Alexander Terekhov

unread,
May 13, 2002, 11:50:12 AM5/13/02
to

"Slava M. Usov" wrote:
>
> "Alexander Terekhov" <tere...@web.de> wrote in message
> news:3CDF67F7...@web.de...
>
> [...]
>
> > http://support.microsoft.com/default.aspx?scid=kb;EN-US;q173260
> > ("PRB: Synchronization Failure When Debugging (Q173260)")
> >
> > that "entire" stuff is just yet another illustration
> > of "total brain-damage" principle that rules at MS
> > location...
>
> Did you read the article by keywords, such as "probably" and "no guaranteed
> workaround", skipping the contents completely?

No; I did read it "completely".

> If you did not notice, the
> article says that while a thread is suspended, PulseEvent() will not wake
> the thread,

Not only PulseEvent. Read again.

> which is the intended and documented behavior:

*Intended* "brain-damage" is even WORSE than "accidental"
one. "Documented" is GOOD, though! ;-)

[...]


> Now how is that different from the KB article? The bottom line, PulseEvent()
> works as it is advertised; that debugging is difficult is irrelevant.

Irrelevant to what? That's exactly what makes this particular
piece of Win32 (among many others such pieces) *totally
brain-damaged*. Without that "feature", cond.vars. would be
fairly "simple" to implement/emulate (just an illustration):

http://groups.google.com/groups?as_umsgid=3AEAC433...@web.de

:>---------- Algorithm 1 ----------
:>given:
:>ex_mutex - mutex
:>cond - autoreset event
:>nWaiters - int
:>
:>wait(timeout) {
:> nWaiters++
:> bTimedOut=SignalAndWait(ex_mutex, cond, timeout)
:> lock ex_mutex
:> nWaiters--
:> return bTimedOut
:>}>
:>signal(bAll) {
:> do (bAll?nWaiters:1 times) {
:> PulseEvent(cond)
:> }
:>}
:>---------- ---------- ----------
:>This pseudocode assumes that ex_mutex is always held by the thread
calling
:>signal, ....

regards,
alexander.

Alexander Terekhov

unread,
May 13, 2002, 12:07:58 PM5/13/02
to

Lucian Wischik wrote:
>
> [pthreads]
>
> I love the way Windows uses events rather than condition variables! The
> fact that a "Signal" on an event isn't lost even though no-one's waiting
> on it (while a condition variable signal does get lost) means you don't
> have to wrap your brain around that horrendous
> release-mutex-then-wait-then-reacquire-mutex command. Windows signals seem
> way more natural.

My "usual ramblings" aside (see the beginning of that thread,
if you are interested[1] ;-)), check out this conversation
(and, please, don't miss the "coding exercise" ;-) ;-)):

http://www.codeproject.com/interview/herbsutter3032002.asp?forumid=3455&tid=131105&select=142170&fr=51#xx142170xx
(CV:"William E. Kempf" vs. EVENT:"Tim Smith" ;-))

HTH.

regards,
alexander.

P.S. Lucian, STUDY condvars (or, even better, the entire
pthreads altogether)! *You won't regret, really!*

[1]
http://www.codeproject.com/interview/herbsutter3032002.asp?forumid=3455&tid=131105&select=133959#xx133959xx

Lucian Wischik

unread,
May 13, 2002, 12:32:08 PM5/13/02
to
Alexander Terekhov <tere...@web.de> wrote:
>My "usual ramblings" aside (see the beginning of that thread,
>if you are interested[1] ;-)), check out this conversation
>(and, please, don't miss the "coding exercise" ;-) ;-)):
>P.S. Lucian, STUDY condvars (or, even better, the entire
> pthreads altogether)! *You won't regret, really!*

I am interested. I taught condvars to students. I went to work at Compaq
SRC where they came up with one of the first real implementations of
condvars, partly because of that and because of their lovely language
Modula3. Coincidentally, the project I was working on there was proving
the correctness of programs written using Win32 primitives. Your "usual
ramblings" weren't a real argument, just bluster. The thread you pointed
me to was the same.

My experience was that win32 events were easier to program with because
they avoided the horrendous brain-twists needed to get around condvars. I
experience this brain-twist when teaching condvars to students. I haven't
taught win32 events yet. But when I figured out how to program the basic
multithreaded structures with events, I loved the solutions that were
possible.

josh

unread,
May 13, 2002, 7:58:33 AM5/13/02
to
On 13 May 2002 15:08:20 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> [pthreads]
>
> I love the way Windows uses events rather than condition variables! The
> fact that a "Signal" on an event isn't lost even though no-one's waiting
> on it
If you PulseEvent and no one's looking, it'll be lost.

Lucian Wischik

unread,
May 13, 2002, 1:09:10 PM5/13/02
to

So use SetEvent, which won't be!

PulseEvent smells like it was designed for one particular and bizarre
situation and isn't worth using in general because you don't encounter
that exact situation.

I'd agree that the main weakness of win32 events is that it's harder to
broadcast. And maybe people were trying (misguidedly) to use PulseEvent
for a broadcast. But I've found that different design of the
multithreading works better than trying to simulate the condvar broadcast.

josh

unread,
May 13, 2002, 8:37:45 AM5/13/02
to
On 13 May 2002 17:09:10 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> josh <jo...@xtreme.net> wrote:
> >On 13 May 2002 15:08:20 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> >> I love the way Windows uses events rather than condition variables! The
> >> fact that a "Signal" on an event isn't lost even though no-one's waiting
> >> on it
> >If you PulseEvent and no one's looking, it'll be lost.
>
> So use SetEvent, which won't be!

If you use SetEvent on a manual event it'll release everyone waiting on it and
will leave the event in the "signalled" state till you ResetEvent. PulseEvent
will let go only one thread and reset the event. And in both cases if no one was
waiting, the signal occurrence will be lost.

> PulseEvent smells like it was designed for one particular and bizarre
> situation and isn't worth using in general because you don't encounter
> that exact situation.
>
> I'd agree that the main weakness of win32 events is that it's harder to
> broadcast.

Actually, I like Win32 events better than condition variables. You can broadcast
with a manual version. It's in general more straighforward to use, I think.

> And maybe people were trying (misguidedly) to use PulseEvent
> for a broadcast.

Not at all, it's there to release one thread on a manual reset event. With
pthreads you can't even guarantee such a thing, it's, unless I'm mistaken, at-
least-one thread release.

Lucian Wischik

unread,
May 13, 2002, 1:47:18 PM5/13/02
to
josh <jo...@xtreme.net> wrote:
>[So use SetEvent!]

>If you use SetEvent on a manual event it'll release everyone waiting on it and
>will leave the event in the "signalled" state till you ResetEvent...

>And in both cases if no one was waiting, the signal occurrence will be lost.

What do you mean "the signal occurrence will be lost"? The fact that it
was signalled has not been lost. So you must mean something else by
"occurence" but I don't know what.

Slava M. Usov

unread,
May 13, 2002, 2:18:29 PM5/13/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CDFE0B4...@web.de...

> Not only PulseEvent. Read again.

Yeah, right. The pair of SetEvent()/ResetEvent() which is the same thing
given the usage scenario in question.

> *Intended* "brain-damage" is even WORSE than "accidental"
> one. "Documented" is GOOD, though! ;-)

Until you show what so _intrinsically_ brain damaged there is in
PulseEvent() this is, sorry, merely hot air.

> Irrelevant to what? That's exactly what makes this particular
> piece of Win32 (among many others such pieces) *totally
> brain-damaged*. Without that "feature", cond.vars. would be
> fairly "simple" to implement/emulate (just an illustration):

Excuse me. The world is not centered around the condition vars. Some types
may find it difficult to believe, but just assume that. Now, apart from the
conditional vars, or, more specifically, from the difficulty to broadcast
with Win32 events, what is so brain-damaged about them? You're trying to use
the tool that is not fit for the job, no wonder it hurts. If you do not know
how to go about without using events, ask, repeating that "one of Win32
mechanism is not a good foundation for X, so that Win32 mechanism is brain
damaged, and, BTW, the whole Win32 is brain damaged" will get you nowhere.

S


Michael J. Saletnik

unread,
May 13, 2002, 6:20:56 PM5/13/02
to
josh <jo...@xtreme.net> writes:

> If you use SetEvent on a manual event

...


> And in both cases if no one was
> waiting, the signal occurrence will be lost.

I believe this statement is wrong. According to MSDN:

The state of a manual-reset event object remains signaled until it
is set explicitly to the nonsignaled state by the ResetEvent
function. Any number of waiting threads, or threads that
subsequently begin wait operations for the specified event object
by calling one of the wait functions, can be released while the
object's state is signaled.

--
{michael}

Michael J. Saletnik

unread,
May 13, 2002, 6:35:26 PM5/13/02
to
ljw...@cus.cam.ac.uk (Lucian Wischik) writes:
> My experience was that win32 events were easier to program with because
> they avoided the horrendous brain-twists needed to get around condvars. I

I think it all depends on need. If all you need is to sleep until
signalled, then an event is an ideal solution. If, however, you have a
predicate that must be tested when you wake up, then that predicate
must be tested while holding the guarding mutex. And of course it
avoids having to think about most race conditions to combine
sleep/wake with lock acquire/release in one call (not all race
conditions, of course, the lost wake-up problem's still there if you
don't do it right).

To emulate that full behavior using only Win32 events requires the
guarding mutex, a manual-reset event, and a semaphore, and
understanding the "brain-twist" semantics anyway to avoid the race
conditions. For that, I'd rather just use a condition variable.

Having participated in an implementation of condition variables on
Win32, it was very difficult to get right. Having to write it all out
by ourselves made it clear exactly how it worked; however, it wasn't
worth it.
:-)

--
{michael}

josh

unread,
May 13, 2002, 6:50:23 PM5/13/02
to
On Mon, 13 May 2002 22:20:56 GMT, "Michael J. Saletnik" <mic...@ties.org> wrote:
> josh <jo...@xtreme.net> writes:
>
> > If you use SetEvent on a manual event
> ....

> > And in both cases if no one was
> > waiting, the signal occurrence will be lost.
>
> I believe this statement is wrong. According to MSDN:

Taken out of context, it is. I said if it's reset at some point before the wait.

Lucian Wischik

unread,
May 14, 2002, 2:45:14 AM5/14/02
to
Michael J. Saletnik <mic...@ties.org> wrote:
>I think it all depends on need. If all you need is to sleep until
>signalled, then an event is an ideal solution. If, however, you have a
>predicate that must be tested when you wake up, then that predicate
>must be tested while holding the guarding mutex.

WaitForEvent();
AcquireMutex();
test predicate
ResetEvent();
...
ReleaseMutex();

You can acquire the predicate after the event. So I don't understand why
you feel this "If..." is important.


>And of course it avoids having to think about most race conditions to
>combine sleep/wake with lock acquire/release in one call (not all race
>conditions, of course, the lost wake-up problem's still there if you
>don't do it right).

But I don't think you see the lost wake-up with events because it doesn't
get lost. Unless I misunderstand you.

josh

unread,
May 13, 2002, 9:57:33 PM5/13/02
to
On 14 May 2002 06:45:14 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> Michael J. Saletnik <mic...@ties.org> wrote:
> >I think it all depends on need. If all you need is to sleep until
> >signalled, then an event is an ideal solution. If, however, you have a
> >predicate that must be tested when you wake up, then that predicate
> >must be tested while holding the guarding mutex.
>
> WaitForEvent();
> AcquireMutex();

This is not atomic. I think that's what he means. With cond vars you do that thing
above in one shot. When you wake up from the event you got your mutex taken out,
in Win32 you can't do that. It is a useful construct, but imo, it's not
sufficiently general to be elevated to an only available event-related API call.
That's why I think Win32, in general, is better (though it lacks the event/mutex
combination, just as it used to lack SignalAndWait construct; perhaps it should
be added to the API.)

Lucian Wischik

unread,
May 14, 2002, 3:09:29 AM5/14/02
to
josh <jo...@xtreme.net> wrote:
>On 14 May 2002 06:45:14 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
>> WaitForEvent();
>> AcquireMutex();
>This is not atomic. I think that's what he means. With cond vars you do
>that thing above in one shot.

I think it's stronger than that. With condvars you *HAVE TO* do the
release-mutex-then-wait atomically, else you might lose the event. With
events, you don't have to do it atomically, since the event remains
signalled.

josh

unread,
May 13, 2002, 10:47:46 PM5/13/02
to
On 14 May 2002 07:09:29 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> josh <jo...@xtreme.net> wrote:
> >On 14 May 2002 06:45:14 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> >> WaitForEvent();
> >> AcquireMutex();
> >This is not atomic. I think that's what he means. With cond vars you do
> >that thing above in one shot.
>
> I think it's stronger than that. With condvars you *HAVE TO* do the
> release-mutex-then-wait atomically, else you might lose the event. With
> events, you don't have to do it atomically, since the event remains
> signalled.

Well, that's the same thing only backwards <g>. If you *need* such an operation,
then with pthreads there's a built-in construct. Win32 doesn't have it, and maybe
it should, but you should also be able to simply wait, w/o any mutexes involved.
That, unless I'm mistaken, pthreads don't allow, and I can't quite honestly,
figure why.

Alexander Terekhov

unread,
May 14, 2002, 3:29:23 AM5/14/02
to

Lucian Wischik wrote:
[...]

> But when I figured out how to program the basic
> multithreaded structures with events, I loved the solutions that were
> possible.

Care to show us some "solutions" you loved?

BTW, I figured out that MS-event is just:

a) mutex for locking;

b) silly "signaled" state -- only good for race conditions
(unless event is "protected" via yet another mutex/multi-
wait, or is completely disjoined from (does NOT mirror)
any "real" application state -- shared data, I mean).

c) "real" cond.var (plus that internal "signaled" predicate)
for waiting.

Here is the pseudo-code (w/o "pulsing" and thread cancellation
handling, though):

init event:

event->manual = <manual_mode>
event->signaled = <initial_state>
init event->mtx // mutex
init event->condvar // condition variable

end init event

wait for event:

lock event->mtx

while NOT event->signaled
cond_wait event->condvar,event->mtx

if NOT event->manual // Auto-reset
event->signaled = FALSE

unlock event->mtxLock

end wait for event

set event:

lock event->mtx
event->signaled = TRUE
unlock event->mtx

if event->manual
broadcast event->condvar
else
signal event->condvar

end set event

reset event:

lock event->mtx
event->signaled = FALSE
unlock event->mtx

end reset event

And (BTW too), "pseudo"-semaphore[1] (again, no-cancel):

init sema

sema->count = <initial_state>
sema->waiting = 0
sema->signaled = 0
init sema->mtx // mutex
init sema->condvar // condition variable

end init sema

lock sema

lock sema->mtx

if 0 == sema->count
++sema->waiting
do
// either ignore signal-"stealing" which
// could occur due to spurious wakeups/
// timeouts (for timedlock) or just add
// some extra checking/handling here and
// in unlock
cond_wait sema->condvar,sema->mtx
while 0 == sema->signaled
--sema->signaled
else
--sema->count

unlock sema->mtx

end lock sema

unlock sema

lock sema->mtx

if 0 == sema->waiting
++sema->count
unlock sema->mtx
else
--sema->waiting
++sema->signaled
unlock sema->mtx
signal sema->condvar
end else

end unlock sema

regards,
alexander.

[1]
http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap04.html#tag_04_15
(see "Semaphore"/"Semaphore Lock Operation"/"Semaphore Unlock
Operation"

and, perhaps:

http://groups.google.com/groups?selm=3CDBD51B.3B7839F8%40web.de

Alexander Terekhov

unread,
May 14, 2002, 4:04:17 AM5/14/02
to

"Slava M. Usov" wrote:
[...]
> Excuse me.

Ok. No problems, "pardon" is given (feel free to
punish yourself -- via using brain-damaged events ;-)).

> The world is not centered around the condition vars. Some types
> may find it difficult to believe, but just assume that.

I assume that. Even more: unfortunately, the world (really
large population) IS centered around brain-damaged events;
I do realize it, Slava.

> Now, apart from the
> conditional vars, or, more specifically, from the difficulty to broadcast
> with Win32 events,

Huh?

> what is so brain-damaged about them?

They have state (unless you just "pulse" permanently
"nonsignaled" auto-reset ones [making it stateless,
in effect] emulating STATELESS condvars, thread-
suspension/debug problems aside). That's it. That
"extra" state sort-of-mirrored in the events is

A) absolutely useless for "waiting" w.r.t. some
"real" state change reflected in some shared
data,

and

B) really easy/prompt to introduce race condition,
like MS-folks themselves CONTINUE to demonstrate
here, for example:

http://sources.redhat.com/ml/pthreads-win32/2001/msg00158.html
(silly MSDN articles, I mean)

regards,
alexander.

Alexander Terekhov

unread,
May 14, 2002, 4:14:46 AM5/14/02
to

Lucian Wischik wrote:
>
> josh <jo...@xtreme.net> wrote:
> >On 14 May 2002 06:45:14 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> >> WaitForEvent();
> >> AcquireMutex();
> >This is not atomic. I think that's what he means. With cond vars you do
> >that thing above in one shot.
>
> I think it's stronger than that. With condvars you *HAVE TO* do the
> release-mutex-then-wait atomically,

Yep.

> else you might lose the event.

Nah. *signal* -- else you might fail to unblock
"the right" <awaiting, if any> thread... do a
search on "terekhov tennis" ;-).

> With
> events, you don't have to do it atomically, since the event remains
> signalled.

And that's exactly what makes them totally
brain-damaged, right! ;-)

regards,
alexander.

Alexander Terekhov

unread,
May 14, 2002, 6:03:30 AM5/14/02
to

"Michael J. Saletnik" wrote:
[...]

> Having participated in an implementation of condition variables on
> Win32, it was very difficult to get right.

Could you please show us your impl (it is fairly simple
thing with thread-specific "blockers"/explicitly managed
queue)?

> Having to write it all out
> by ourselves made it clear exactly how it worked; however, it wasn't
> worth it.
> :-)

Why?

regards,
alexander.

Alexander Terekhov

unread,
May 14, 2002, 6:19:09 AM5/14/02
to

"Michael J. Saletnik" wrote:
[...]
> I think it all depends on need.

Right (and intelligence and/or skills ;-)).

> If all you need is to sleep until
> signalled, then an event is an ideal solution.

If all you need is a simple monitor with a boolean state
variable, then just do it -- mutex (for locking), state.var
(shared data that is "monitored" and "controlled" by your
application), and cond.var (for waiting) packaged together
in some "event" structure is all what you need to make it
"work". It is simple (but NOT often needed [in my experience],
though).

regards,
alexander.

Joe Seigh

unread,
May 14, 2002, 6:02:04 AM5/14/02
to

Lucian Wischik wrote:
>
> josh <jo...@xtreme.net> wrote:
> >On 14 May 2002 06:45:14 GMT, ljw...@cus.cam.ac.uk (Lucian Wischik) wrote:
> >> WaitForEvent();
> >> AcquireMutex();
> >This is not atomic. I think that's what he means. With cond vars you do
> >that thing above in one shot.
>
> I think it's stronger than that. With condvars you *HAVE TO* do the
> release-mutex-then-wait atomically, else you might lose the event. With
> events, you don't have to do it atomically, since the event remains
> signalled.
>

You're right that you *HAVE TO* hold the mutex to do a wait. It was deliberately
designed that way to force, err..., I mean encourage, proper multithreaded programming
practices.

But stronger wouldn't be the right term to use. Think in terms of lower level primitives
and higher level constructs. You wouldn't call assembly language stronger than java. Each
has its place. The lower level primitive to do non-lossy signaling without locks would be
something like eventcounters which pthreads doesn't have. (note to others: constructing
a lower level primitive out of higher level constructs somehow isn't the same thing).

Win32 doesn't have eventcounters either. The problem with win32 events, if I remember correctly,
is that it's problematic to have multiple waiters on the event. If you do it gets really
nasty coordinating the resetting of the event properly, or else you have possible race or
hang conditions being ignored, possibly out of cluelessness. And generally you don't hear
win32 programmers complaining of the former all that much.

Joe Seigh

Alexander Terekhov

unread,
May 14, 2002, 9:33:23 AM5/14/02
to

< got a few spare minutes -- wanna "bluster" a bit ;-) >

Lucian Wischik wrote:
>
> Alexander Terekhov <tere...@web.de> wrote:
> >My "usual ramblings" aside (see the beginning of that thread,
> >if you are interested[1] ;-)), check out this conversation
> >(and, please, don't miss the "coding exercise" ;-) ;-)):
> >P.S. Lucian, STUDY condvars (or, even better, the entire
> > pthreads altogether)! *You won't regret, really!*
>
> I am interested.

I am too.

> I taught condvars to students.

Uhmmm. Really? "No comments". ;-)

> I went to work at Compaq

Oh! That's just yet ANOTHER really GOOD reason why you should
buy a book written by one of your former colleagues... and it
could really help you w.r.t. "teaching condvars to students",
I guess!

> SRC where they came up with one of the first real implementations of
> condvars, partly because of that and because of their lovely language
> Modula3.

You mean: (*Alert*: "HIGHLY RECOMMENDED READING", folks)

http://gatekeeper.research.compaq.com/pub/DEC/SRC/research-reports/SRC-020.ps.gz
http://216.239.39.100/search?q=cache:cv84gdXblOIC:gatekeeper.research.compaq.com/pub/DEC/SRC/research-reports/SRC-020.ps.gz
(text version; BTW: Joe, they even mention "eventcount"! ;-))

> Coincidentally, the project I was working on there was proving
> the correctness of programs written using Win32 primitives.

Rather silly project, IMHO. The usual outcome is already known
to "everyone and his dog" out there -- mostly *INCORRECT*; just
check out MSDN "publications"! ;-)

> Your "usual
> ramblings" weren't a real argument, just bluster. The thread you pointed
> me to was the same.

Yeah, for example:

http://www.codeproject.com/interview/herbsutter3032002.asp?forumid=3455&tid=131105&select=142198&fr=51&exp=0#xx142198xx

"I've given you the proof, but you've not "wanted to see the
forest for the trees". Tim, please, I know you're smart and
I respect your opinions, so it's a shame that things are very
rapidly spiraling into flame territory. Try to objectively
listen to what I've said and then try and prove me wrong. You
insist on proof from me, but this is one of those scientific
topics in which absolute proof isn't possible. I've laid the
ground work, however, for you to prove me wrong. If you can't
do so then my assertion is correct, because I'm not claiming
that it's impossible, only that no one's done it yet which
makes the event "unsafe" in this context.

So... here's the ground work. Let's take the simplest "hello
world" MT example that we've all done numerous times, the
classic "bounded buffer". Show me an implementation using
only mutexes and events (actually, to prove that events are
"safe" you'd probably have to do this with a single event
and a single mutex, but I'll let you use any number of these
you care to) that is free of race conditions. Heck, if you
think the classic example is somehow specifically designed
to be problematic for events I'll settle for *any* example
that uses only events, mutexes and some shared resource. If
you can prove me wrong you'll make my life soooo much easier,
so believe it or not I'm rooting for you to succeed.

William E. Kempf"

> My experience was that win32 events were easier to program with because
> they avoided the horrendous brain-twists needed to get around condvars.

"horrendous brain-twists needed to get around condvars"

aside, PLEASE demonstrate to us that "win32 events were
easier to program with" using Bill's "ground work", for
example.

regards,
alexander.

Keith Willis

unread,
May 14, 2002, 10:15:18 AM5/14/02
to
On Tue, 14 May 2002 15:33:23 +0200, Alexander Terekhov
<tere...@web.de> wrote:

>Lucian Wischik wrote:
>> I taught condvars to students.
>
>Uhmmm. Really? "No comments". ;-)

Alexander, adding a 'smiley' does not excuse the sarcasm which
precedes it. You do this a lot, and it's not big, and it's not
clever.

You seem to delight in putting down, or questioning, the opinions and
experiences of others in thread after thread after thread. In my
opinion, you are far and away the most contentious contributor to
c.p.t.

I'm sure you don't particularly care, but you will now spend a couple
of weeks in my killfile while I decide if the remaining content in
c.p.t. is worth the hassle of having to wade through your verbiage.

--
PGP key ID 0xEB7180EC
Available from http://www.keyserver.net

Michael J. Saletnik

unread,
May 14, 2002, 10:12:10 AM5/14/02
to
Alexander Terekhov <tere...@web.de> writes:
> Could you please show us your impl (it is fairly simple

I cannot; it was for a proprietary product. In fact, I don't work
there anymore so I can't even look at the code...
:-(

However, it pretty much followed the designs available in papers that
can be found via Google. A waiter count guarded by a mutex, the
"outer" mutex of the monitor, and a semaphore of waiters.

> > Having to write it all out by ourselves made it clear exactly how
> > it worked; however, it wasn't worth it.

> Why?

Because it was a cross-platform product, therefore it required using
the same semantic regardless of platform. We chose to do this in terms
of condition variables, with a trivial implementation on *nix systems,
but we then had to develop, maintain, and ensure through significant
testing that we had exactly the same behavior for the nontrivial Win32
implementation.

Joe Seigh <jse...@genuity.com> writes:
> The problem with win32 events, if I remember correctly, is that it's
> problematic to have multiple waiters on the event. If you do it
> gets really nasty coordinating the resetting of the event properly,

This one I'll agree with. It's established elsewhere in this thread
that if you try the construct:
* lock mutex
* test predicate
* unlock mutex
* go to sleep on event
that the event could be signalled between the two steps. To prevent
that signalling being lost, a manual-reset event is needed. However,
once you do that, there's no way to restrict it to only one thread
being released (ie, pthread_cond_signal as opposed to
pthread_cond_broadcast).

At least MSDN didn't imply any way to do it.
:-)

--
{michael}

tester

unread,
May 14, 2002, 12:29:14 PM5/14/02
to

Keith Willis wrote:
>
> On Tue, 14 May 2002 15:33:23 +0200, Alexander Terekhov
> <tere...@web.de> wrote:
>
> >Lucian Wischik wrote:
> >> I taught condvars to students.
> >
> >Uhmmm. Really? "No comments". ;-)
>
> Alexander, adding a 'smiley' does not excuse the sarcasm which
> precedes it. You do this a lot, and it's not big, and it's not
> clever.

Maybe. I just wonder: did I really somehow/somewhere/sometime
express the desire to have/get an "excuse" via "adding a
'smiley'" and/or that I think that it's "clever"? I think,
I did NOT.

> You seem to delight in putting down, or questioning, the opinions and
> experiences of others in thread after thread after thread.

Feel free to interpret my posts here in whatever way you
like/want.

> In my
> opinion, you are far and away the most contentious contributor to
> c.p.t.

Thanks for the compliment, really. <NO smiley>

> I'm sure you don't particularly care, but you will now spend a couple
> of weeks in my killfile while I decide if the remaining content in
> c.p.t. is worth the hassle of having to wade through your verbiage.

Don't waste time "deciding" -- join the discussions
("remaining content in c.p.t.", I mean); personally,
I'd be quite happy and really interested *to wade
through your verbiage* here if it would include some
*technical and on-topic content*... in addition to
your own "putting down, or questioning, the opinions
and..." low-rank-flames-ONLY, like this quoted article
from you (and the one preceding this one here too BTW;
your recent "Windows Washer" -- "costs less than
US$30"-one aside ;-) ;-)).

regards,
alexander.

Arnold Hendriks

unread,
May 14, 2002, 12:50:25 PM5/14/02
to
In comp.programming.threads Alexander Terekhov <tere...@web.de> wrote:
> Lucian Wischik wrote:
> [...]
>> But when I figured out how to program the basic
>> multithreaded structures with events, I loved the solutions that were
>> possible.

> Care to show us some "solutions" you loved?
> BTW, I figured out that MS-event is just:

> c) "real" cond.var (plus that internal "signaled" predicate)
> for waiting.

There exists a "real" cond.var implementation inside Win32? Now that'd be
great, if there were only a way to access it...

--
Arnold Hendriks <a.hen...@b-lex.com>
B-Lex Information Technologies, http://www.b-lex.com/

Slava M. Usov

unread,
May 14, 2002, 2:35:35 PM5/14/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CE0C501...@web.de...

> Ok. No problems, "pardon" is given (feel free to
> punish yourself -- via using brain-damaged events ;-)).

Looks like it's your favorite style -- take a couple of words out of
context, demonstrate how clever you are by exploiting the out-of-context
phrase and, when reminded of the context, switch the topic completely, as
you did with debugging and suspending. Typical smoke and mirrors practice,
the weapon of choice in religious debates. Back on the topic. I asked to
excuse me "for interrupting your stream of eloquence as having no relation
to events whatsoever". "Because events are not conditional variables nor
were they designed to be suitable for implementing the latter." I hate to be
so explicit but apparently I will have for a while.

As others have said a dozen of times in this thread, events are one thing
and conditional variables another thing. Events are conceptually simpler
than condvars [e.g., you don't need an external mutex with events]. Events
may come more handy in certain situations [e.g., wait on multiple events:
try that with condvars when the sources do not cooperate]. Finally you can
implement conditional variables without ever touching events [having
diagonally scanned the long article you referenced yesterday, I can tell
you know that]. I am not commenting on your demonstrating of events'
brain-damagedness as you again slipped to comparing them to conditional
variables... it is true that some people like oranges so much that they hate
apples, but I find comparing both quite fruitless.

I completely accept and share the viewpoint that Win32 events may be
unexpectedly difficult to use in specific applications and many
implementations using events have subtle problems. PulseEvent() is
especially hard to get right for the uninitiated. That MS is as prone to
that as everybody else is of little surprise... [damn I said I wouldn't
comment :-)]. I will still maintain that for other applications events are a
perfect fit. I could mention a few cases but as you are unlikely to stop
using your favorite "brain-damaged" idioms I should better save myself that
typing.

S

Alexander Terekhov

unread,
May 14, 2002, 6:22:04 PM5/14/02
to

"Slava M. Usov" wrote:
>
> "Alexander Terekhov" <tere...@web.de> wrote in message
> news:3CE0C501...@web.de...
>
> > Ok. No problems, "pardon" is given (feel free to
> > punish yourself -- via using brain-damaged events ;-)).
>
> Looks like it's your favorite style -- take a couple of words out of
> context, demonstrate how clever you are by exploiting the out-of-context
> phrase and, when reminded of the context, switch the topic completely, as
> you did with debugging and suspending.

Excuse me (BTW, feel free to "exploit" this couple of words ;-)),
but I don't understand your "switch topic" bit w.r.t. "as I did
with debugging and suspending". Could you please elaborate?

> Typical smoke and mirrors practice,
> the weapon of choice in religious debates

I'm a smoker (do you remember BELOMOR/PRIMA/etc.? ;-))
and even heard of mirrors, but never heard of that
debating practice. How about e-mail on that, Slava?

> Back on the topic.

That's good (BTW, compare the number of words
in our off-topic-blah-blah' portions ;-)).

> I asked to
> excuse me "for interrupting your stream of eloquence as having no relation
> to events whatsoever". "Because events are not conditional variables

See below.

> nor were they designed to be suitable for implementing the latter."

Uhmm. Whether they were designed to be suitable or not, they
COULD be used for implementing/emulating the latter, AFAICT.

> I hate to be so explicit but apparently I will have for a while.

Ok. That always helps... presuming that you'll succeed in
achieving that goal. ;-)

> As others have said a dozen of times in this thread, events are one thing
> and conditional variables another thing.

I also said *exactly that* -- did I say that cond.vars
ARE brain-damaged and/or error-prone? I think: NO! ;-)

> Events are conceptually simpler than condvars

That's wrong.

> [e.g., you don't need an external mutex with events].

But you DO need "internal mutex"... to communicate the
state of shared "flag" (and associated application shared
data) among different threads (processors -- hint: "memory
sync".), to begin with; apart from "blocking" - with NO
clear separation between "locking" and "waiting" (see POSIX
threads Rationale), etc.

> Events may come more handy in certain situations [e.g.,
> wait on multiple events: try that with condvars

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Oh <sigh>... My, *WaitForMultiple*... Don't get/provoke
me on this, please. FYI:

http://groups.google.com/groups?selm=slrn7hiau9.1q3.kaz%40ashi.FootPrints.net
(*HTH*, I especially like "...president of the United States." bit ;-))

> when the sources do not cooperate].

Uhmm. What do you mean? If "sources do not cooperate"
they simply AREN'T threads -- what are you talking
about?

> Finally you can
> implement conditional variables without ever touching events

Well, MS-auto-reset event is also known to ABM-world as BIN.SEMA
(pulsing aside), to begin with. And, semas (and MS-ones with that
silly/brain-damaged "max" count, especially) aren't really much
better than events *for shared memory (with it, I mean) cooperative
sync.protocols and threading: "medium to fine-grained structuring
mechanism for parallelism in an application" (signals/interrupts
aside)*. Read the POSIX threads Rationale on semas, please (I've
already posted the {indirect} link somewhere in this thread, and,
BTW, that old DEC-SRC research paper also mentioned it).

> [having
> diagonally scanned the long article you referenced yesterday, I can tell
> you know that].

I'm not sure what you imply by "that", really.

> I am not commenting on your demonstrating of events'
> brain-damagedness as you again slipped to comparing them to conditional
> variables... it is true that some people like oranges so much that they hate
> apples, but I find comparing both quite fruitless.

OK. See below.

> I completely accept and share the viewpoint that Win32 events may be
> unexpectedly difficult to use in specific applications and many
> implementations using events have subtle problems. PulseEvent() is
> especially hard to get right for the uninitiated. That MS is as prone to
> that as everybody else is of little surprise... [damn I said I wouldn't
> comment :-)]. I will still maintain that for other applications events are a
> perfect fit.

That's really interesting...

> I could mention a few cases but as you are unlikely to stop
> using your favorite "brain-damaged" idioms I should better save
> myself that typing.

Slava, I *PROMISE* NOT TO USE "brain-damaged" idioms
(and, heck, even ";-)" idioms) in my replies to your
followup(s) that would *really show a few cases where
events are a perfect fit*.

Please!

Deal? ;-)

regards,
alexander.

josh

unread,
May 14, 2002, 10:27:31 PM5/14/02
to
That's it, that's it. Kick him in the ass.

On Tue, 14 May 2002 20:35:35 +0200, "Slava M. Usov" <stripit...@gmx.net>
wrote:


> "Alexander Terekhov" <tere...@web.de> wrote in message
> news:3CE0C501...@web.de...
>
> > Ok. No problems, "pardon" is given (feel free to
> > punish yourself -- via using brain-damaged events ;-)).
>
> Looks like it's your favorite style -- take a couple of words out of

> context,...

Slava M. Usov

unread,
May 15, 2002, 6:18:16 AM5/15/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CE18E0C...@web.de...

> Excuse me (BTW, feel free to "exploit" this couple of words ;-)),
> but I don't understand your "switch topic" bit w.r.t. "as I did
> with debugging and suspending". Could you please elaborate?

I started following this thread when it was crossposted to
microsoft.public.win32.programmer.kernel. The message that drew my attention
was the one where you cited the KB article dealing with PulseEvent() and
debugging, with some annotations :-). My only objection to that was and
still is that there is no point in citing that article as if it violated
some agreement between programmers and MS, since MS _had_ put all the
relevant details in the synopsis of that API routine. I do not really care
much about events being inferior or superior to condition variables, they
are just different. That's another thing that I stand by. While you always
end up comparing the two. So. Now you do not say that "events are bad
because threads can be suspended" [for me, this is ridiculous since they are
pretty much independent of each other], now you mention other things --
fine, you may have a point, but I never wanted to discuss that, for the
reason I explained above.

> I'm a smoker (do you remember BELOMOR/PRIMA/etc.? ;-))

Gave up a few years ago, after a major dental overhaul and lots of horror
smoke-tar-high-temperature-teeth stories told by the dentist. The bills sort
of confirmed his narrative :-). And yes I remember that stuff, how is it
possible to forget it? :-)

> and even heard of mirrors, but never heard of that
> debating practice. How about e-mail on that, Slava?

OK

> Uhmm. Whether they were designed to be suitable or not, they
> COULD be used for implementing/emulating the latter, AFAICT.

Yes, and the emphasis is proper. And you could use a nuke to deal with seeds
in your garden.

> > [e.g., you don't need an external mutex with events].
>
> But you DO need "internal mutex"... to communicate the
> state of shared "flag" (and associated application shared
> data) among different threads (processors -- hint: "memory
> sync".), to begin with; apart from "blocking" - with NO
> clear separation between "locking" and "waiting" (see POSIX
> threads Rationale), etc.

Not necessarily. Events may be used to communicate things without any
synchronization at all [OK, events _are_ a synchronization mechanism, but
here I'm using the word in the narrow sense of having two or more threads
interlock]. A simple example that I see every other day in the real world
software: a thread that does things periodically. That thread must terminate
upon some condition. The archetypical Win32 idiom for that is an event for
"time to quit" and WaitForSingleObject() with a timeout for periodical
wake-up. You could do the same with a condvar, but it takes another boolean
variable, to say nothing of the mandatory ex_mutex. Events are conceptually
simpler in _this_ case.

> Oh <sigh>... My, *WaitForMultiple*... Don't get/provoke
> me on this, please. FYI:
>
>
http://groups.google.com/groups?selm=slrn7hiau9.1q3.kaz%40ashi.FootPrints.ne
t
> (*HTH*, I especially like "...president of the United States." bit ;-))

Good points, but not very convincing. For the one place of sleeping, this is
exactly how NT kernel is implemented, but that place may have a variable
length list of waitable dispatcher objects, and when one of them becomes
signaled it is quite simple for the scheduler to wake the thread if it is an
"any" wait, or traverse the whole list it is the an "all" wait. When I say
"variable length" it is indeed so; the 64 objects limitation is artificial
and probably comes from the inability to communicate larger numbers in the
status code returned by the native API, which is [yes!] silly.

For the starvation, a nice try, but if you're using that, you should think
of that, right?

Not scaling is hardly an issue, as there is seldom a need to wait for more
than just a handful [fixed, at that] of objects.

Then there are many things ultimately saying "not portable", but if I don't
care about that?

The advice to make an aggregate object is good [I anticipated that] but that
is not always possible. Say, if you're doing NT-style async IO, you can't.
If you just using somebody else's code which gives you the handle to wait
on, you can't. If you're waiting on an object exported by a separate process
[by its name], you can't. Granted it may be possible if the design of all
the components takes that into the account, but we are being realistic here,
right?

> Uhmm. What do you mean? If "sources do not cooperate"
> they simply AREN'T threads -- what are you talking
> about?

Sources of events. Code the sets/resets them. See the previous paragraph.

> Well, MS-auto-reset event is also known to ABM-world as BIN.SEMA
> (pulsing aside), to begin with. And, semas (and MS-ones with that
> silly/brain-damaged "max" count, especially)

Well. Then just use 0x7fffffff for that.

> aren't really much
> better than events *for shared memory (with it, I mean) cooperative
> sync.protocols and threading: "medium to fine-grained structuring
> mechanism for parallelism in an application" (signals/interrupts
> aside)*. Read the POSIX threads Rationale on semas, please (I've
> already posted the {indirect} link somewhere in this thread, and,
> BTW, that old DEC-SRC research paper also mentioned it).

I've read that but events already are more than I can handle in this
discussion [short of time, sorry].

> > [having
> > diagonally scanned the long article you referenced yesterday, I can tell
> > you know that].
>
> I'm not sure what you imply by "that", really.

Only that you know that events may be avoided for condvars implementation,
thus eliminating another reason to compare them.

> Slava, I *PROMISE* NOT TO USE "brain-damaged" idioms
> (and, heck, even ";-)" idioms) in my replies to your
> followup(s) that would *really show a few cases where
> events are a perfect fit*.
>
> Please!
>
> Deal? ;-)

Deal. An example above.

S


Alexander Terekhov

unread,
May 15, 2002, 9:44:22 AM5/15/02
to

"Slava M. Usov" wrote:
[...]
> I started following this thread when it was crossposted to
> microsoft.public.win32.programmer.kernel. The message that drew my attention
> was the one where you cited the KB article dealing with PulseEvent() and
> debugging, with some annotations :-). My only objection to that was and
> still is that there is no point in citing that article as if it violated
> some agreement between programmers and MS, since MS _had_ put all the
> relevant details in the synopsis of that API routine.

Again, the problem here is NOT limited to PulseEvent(), the fact
is that SignalObjectAndWait is pretty much useless given the way
how MS implements their "thread model" that allows {annotations}
async.suspend; has {annotations} "suspended" thread state (which
even "break out"[1] already *blocked/waiting* threads) as a part
of their {annotations} thread-model (apart from completion ports
thread pooling -- w.r.t. {annotations} I mean).

I'll reply later (I'm just too busy now/today) to the rest of
your points, but for now, I'd like to "just" drop the following
microsoft.public.win32.programmer.kernel link (and your are quite
familiar with this stuff, Slava... hint: "don't you ever do it"):

http://groups.google.com/groups?threadm=3c4c58b2.21267811%40news.lineone.net
(Subject: Thread synchronization issues)

regards,
alexander.

P.S.

> Now you do not say that "events are bad because threads can be suspended"

In a way, *I DO*.

P.P.S.

http://groups.google.com/groups?threadm=3c4f2281%241%40news.microsoft.com

"....
In win32 you can do it with SignalObjectAndWait (if you use mutex
for locking). "

Well, practically, *you can't* (using SignalObjectAndWait).

"Unfortunately, there is no simple way that
I know of to do this with critical sections."

I know really simple way to do "this" -- click here:

http://sources.redhat.com/pthreads-win32
(see condvars... and, BTW, check out *timed*
"crit.sections" there as well.)

----

[1] Compare/consider (somewhat related thing, IMO):

http://www.opengroup.org/onlinepubs/007904975/functions/pthread_cond_wait.html
(please don't miss the "RATIONALE" section, "Performance of...", etc. --
HTH)

"....
If a signal is delivered to a thread waiting for a condition
variable, upon return from the signal handler the thread resumes
waiting for the condition variable as if it was not interrupted,
or it shall return zero due to spurious wakeup.
...."

Alexander Terekhov

unread,
May 15, 2002, 10:25:25 AM5/15/02
to

josh wrote:
>
> That's it, that's it.

http://groups.google.com/groups?selm=1104_1013803235%40js3owsj2-2j2-2j

"From: josh (jo...@xtreme.net)
Subject: Re: Can multiple threads set a global variable simultaneously?
Newsgroups: comp.programming.threads
Date: 2002-02-15 16:59:23 PST

Thanks.

On 15 Feb 2002 06:32:35 -0800, tere...@web.de (Alexander Terekhov)
wrote:
...."

> Kick him in the ass.

"pardon" is given (and, btw, there are much better places to kick,
stupid).

regards,
alexander.

Slava M. Usov

unread,
May 16, 2002, 6:48:48 AM5/16/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CE26636...@web.de...

> Again, the problem here is NOT limited to PulseEvent(), the fact
> is that SignalObjectAndWait is pretty much useless given the way
> how MS implements their "thread model" that allows {annotations}
> async.suspend; has {annotations} "suspended" thread state (which
> even "break out"[1] already *blocked/waiting* threads) as a part
> of their {annotations} thread-model (apart from completion ports
> thread pooling -- w.r.t. {annotations} I mean).

Well, that is a completely different angle. Win32 threading has some
shortcomings, I cannot deny that nor can I blame them for that. They were
more or less pioneers in this field. Before Win32 there had been just a
handful of OSes supporting threads natively, and they all were experimental
or in limited use. For that matter, all implementations that use kernel
threads are, as you say, {annotated}; scheduler activations might be a
better approach to threading-enabled OSes: at least they would provide for a
painless implementation of any imaginable synchronization primitive
completely in user mode.


[...]

So? In that thread I never said PulseEvent() or events were anything
different than they are. I'm not saying what you think I'm saying; I'm
saying that I'm compltely satisfied with the way PulseEvent() works, even
though it, well, can rarely be used [and one needs to understand what is
being done]

> > Now you do not say that "events are bad because threads can be
> suspended"
>
> In a way, *I DO*.

That should read "threads are bad", then; regarding that, see above.

[...]

> "Unfortunately, there is no simple way that
> I know of to do this with critical sections."
>
> I know really simple way to do "this" -- click here:
>
> http://sources.redhat.com/pthreads-win32

Yeah, yeah. But then there are semaphores, not events. Indeed, semaphores
are more sensible here, since you always deal with a known number of
waiters, so you don't have to decide who's going to call ResetEvent() and
handle the race conditions it will involve. PulseEvent(), regardless of
thread suspends, can be only used with SignalObjectAndWait(), which is not
portable in Win32 [I wouldn't care, though], plus you must use a
heavy-weight mutex for that.

One thing I don't like about that code, though, is the wait enter/exit
sequence: a gate/internal mutex is acquired, and when it gets pathological,
there are more... lots of contexts switches when there is contention.

S

Joe Seigh

unread,
May 16, 2002, 8:19:02 AM5/16/02
to

"Slava M. Usov" wrote:
> ...]

> Well, that is a completely different angle. Win32 threading has some
> shortcomings, I cannot deny that nor can I blame them for that. They were
> more or less pioneers in this field. Before Win32 there had been just a
> handful of OSes supporting threads natively, and they all were experimental

> or in limited use. [...

Could you explain that a little more? As someone who was doing "multi-threading"
before there was a DOS 1.0 even, I am really curious.

Joe Seigh

Slava M. Usov

unread,
May 16, 2002, 8:49:04 AM5/16/02
to
"Joe Seigh" <jse...@genuity.com> wrote in message
news:3CE3A44F...@genuity.com...

> > more or less pioneers in this field. Before Win32 there had
> > been just a handful of OSes supporting threads natively, and
> > they all were experimental or in limited use.

> Could you explain that a little more? As someone who was doing


> "multi-threading" before there was a DOS 1.0 even, I am really
> curious.

Name your operating system and application of the pre-DOS 1.0 days,
and the number of deployed systems. Also note the "natively" word, which
means in kernel mode and not the LWP-way. That I think will explain it
far better than I can. Besides, "doing stuff" in not the same as "having
huge accumulated experience in stuff [which allows creation of real good
stuff]".

S

Joe Seigh

unread,
May 16, 2002, 9:51:37 AM5/16/02
to

Well, IBM's MVS for one. It had shared memory. An event signaling mechanism
using wait(), post(), and an ecb (event control block) which resided in
shared memory and which had a similar problem with that of win32 events. Sharing
it among multiple waiters was a problem.

Ignorance of prior art doesn't mean there wasn't prior art. It just means that
you get entertaining usenet postings and not so entertaining operating systems.

Joe Seigh

Alexander Terekhov

unread,
May 16, 2002, 10:52:53 AM5/16/02
to

"Slava M. Usov" wrote:
>
> "Joe Seigh" <jse...@genuity.com> wrote in message
> news:3CE3A44F...@genuity.com...
>
> > > more or less pioneers in this field. Before Win32 there had
> > > been just a handful of OSes supporting threads natively, and
> > > they all were experimental or in limited use.
>
> > Could you explain that a little more? As someone who was doing
> > "multi-threading" before there was a DOS 1.0 even, I am really
> > curious.
>
> Name your operating system and application of the pre-DOS 1.0 days,
> and the number of deployed systems. Also note the "natively" word, which
> means in kernel mode and not the LWP-way.

Yeah... "LWP-way" ;-) FYI:

http://groups.google.com/groups?selm=3CC6BDBF.C7CD1A02%40web.de
("Subject: Re: First OS with threads support")

HTH.

regards,
alexander.

Hillel Y. Sims

unread,
May 16, 2002, 11:06:54 PM5/16/02
to

"Slava M. Usov" <stripit...@gmx.net> wrote in message
news:ueMYocM$BHA.1980@tkmsftngp04...

. Win32 threading has some
> shortcomings, I cannot deny that nor can I blame them for that. They were
> more or less pioneers in this field. Before Win32 there had been just a
> handful of OSes supporting threads natively, and they all were
experimental
> or in limited use.

Do you _work_ for Microsoft?...

Slava M. Usov

unread,
May 17, 2002, 9:05:20 AM5/17/02
to
"Hillel Y. Sims" <use...@phatbasset.com> wrote in message
news:it_E8.44747$ja.11...@news02.optonline.net...

>
> "Slava M. Usov" <stripit...@gmx.net> wrote in message
> news:ueMYocM$BHA.1980@tkmsftngp04...

> Do you _work_ for Microsoft?...

Your point being?

S

Slava M. Usov

unread,
May 17, 2002, 9:06:03 AM5/17/02
to
"Joe Seigh" <jse...@genuity.com> wrote in message
news:3CE3BA03...@genuity.com...

[...]

> Well, IBM's MVS for one. It had shared memory. An event signaling
> mechanism using wait(), post(), and an ecb (event control block)
> which resided in shared memory and which had a similar problem with
> that of win32 events.

OK, having a few thousand installations in the world probably qualifies for
a scope larger than "limited". However, the bit on "an event signaling
mechanism" nullifies the whole point: MVS had that, and they had just the
same. I'd like to hear of something that did the right thing, was well
known, relatively widely deployed, and all that ca 1985. If I'm not
mistaken, what was called OS/2 was started at about 1987, a branch of which
later on became NT. I'm not surprised by this similarity between MVS and NT
given the history.

Really, the question is not that hard. By that time, ignoring MVS for the
moment, they might only borrow from VMS or some pure or mixed Unix variant.
VMS, AFAIK, did not have threads by that time; IIRC, they were working on
DECthreads, which later on became POSIX threads. The threading model of NT
had been decided on before that, I believe. What was going on in the Unix
community and academia I do not even want to mention: even if you wanted to
borrow something you could hardly decide what.

S

Slava M. Usov

unread,
May 17, 2002, 9:06:15 AM5/17/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3CE3C7C5...@web.de...

[...]

> http://groups.google.com/groups?selm=3CC6BDBF.C7CD1A02%40web.de
> ("Subject: Re: First OS with threads support")

It wasn't very long ago that Sun officially decided that LWP
might be used by applications directly as threads. Before that, there had
been probably some obstacles. What is happening with Linux _today_
concerning threads and "LWP", I don't want to know, thank you. So, whatever
reason one has for calling their threads LWP means they are different from
threads.

S

Hillel Y. Sims

unread,
May 17, 2002, 10:04:18 AM5/17/02
to

"Slava M. Usov" <stripit...@gmx.net> wrote in message
news:OCA6kNa$BHA.1836@tkmsftngp05...

Hmm, that's not a no. ;-)


Daniel Miller

unread,
May 17, 2002, 1:36:32 PM5/17/02
to
Slava M. Usov wrote:

> "Joe Seigh" <jse...@genuity.com> wrote in message
> news:3CE3A44F...@genuity.com...
>
>
>>>more or less pioneers in this field. Before Win32 there had
>>>been just a handful of OSes supporting threads natively, and
>>>they all were experimental or in limited use.


Excuse me!?! That is revisionist history! The real-time embedded software
industry has been using multiple threads per shared address-space for
multiple decades, long before the release of any Win32 product. The pioneering
work in the computer software industry regarding bringing
multiple-threads-per-shared-address-space products successfully to the
commercial marketplace were the widely-deployed real-time operating systems
(RTOSes) in the late 1970s and early 1980s (plus a large amount of truly
pioneering pre-fully-commercial research/experimental-work 1.5 to 2 decades
before that).

>>Could you explain that a little more? As someone who was doing
>>"multi-threading" before there was a DOS 1.0 even, I am really
>>curious.
>>
>
> Name your operating system and application of the pre-DOS 1.0 days,
> and the number of deployed systems. Also note the "natively" word, which
> means in kernel mode and not the LWP-way. That I think will explain it
> far better than I can. Besides, "doing stuff" in not the same as "having
> huge accumulated experience in stuff [which allows creation of real good
> stuff]".
>
> S


pSOS (a.k.a., pSOSystem, later named pSOS+) was an RTOS from Integrated
Systems Incorporated (now owned by WindRiver Systems) introduced in the early
1980s which has had as its main claim to fame, since its early days, 1)
richly-expressive multiple-threads-per-shared-address-space, 2) synchronization
mechanisms between those threads, and 3) asynchronous
multiproducer-multiconsumer unit-of-work hand-off mechanisms between threads
(a.k.a., message-queues). If you have ever made a telephone call or used the
Internet, your communication is likely to have been carried across continents &
oceans by at least one network-element running pSOS+ internally. Many military
products also run pSOS+ internally. Following 1960s-era conventions in the
multiple-threads-per-address-space research which referred to threads as
"processes" or "tasks", threads are called tasks in pSOS which was one of the
commercially-viable & wide-deployed RTOSes to appear during the late 1970s &
early 1980s. I think that we all agree that the telephone network and military
systems were widely deployed before Win32.

UNIX System V Release 4.1MP (and its related bretheren UNIX SVR4.2, UnixWare,
and Solaris 2.X) with UNIX International threads (i.e., before POSIX real-time
extensions and before Win32's threads) shipped in 1992 if I remember correctly.
Throughout the 1990s versions of UNIX & Solaris incorporated the features
and/or source code from UNIX SVR4.1MP. I think that we all agree that Sun
workstations running Solaris 2.X were widely deployed before Win32.

Mentor Graphics' VRTX (pronounced "vertex") and WindRiver's VxWorks are also
RTOSes whose multiple-threads-per-shared-address-space capabilities have been
used on software embedded within telecommunications & military equipment for
multiple decades. If you have ever made a telephone call or used the Internet,
your communication is likely to have been carried across contitents & oceans by
at least one network-element running VxWorks internally. Many military products
also run VxWorks internally. I think that we all agree that the telephone
network and military systems were widely deployed before Win32.

VRTX: http://www.mentor.com/embedded/vrtxos/
VxWorks & pSOS: http://www.windriver.com/products/html/os.html

The following excerpt is from
http://www.faqs.org/faqs/os-research/part1/section-10.html

"On a side note, threads have been in continuous use in telecommunications
applications for quite a long time."

where "quite a long time" is in presented in the context of discussing the
history of threads prior to existence of UNIX in the early 1970s.

Evidence of RTOS tasks predating the 1980s & 1990s emergence of the
popularity of threads in Mach, UNIX SVR4, and Win32.

http://groups.google.com/groups?q=RTOS+tasks+history&hl=en&lr=&selm=36701227.548B7573%40lapel.com&rnum=2
http://www.dedicated-systems.com/encyc/publications/faq/rtfaq.htm

Evidence that RTOSes' use of the term "task" for what is now popularly called
"thread" in general-purpose operating systems predates the term "thread":


http://groups.google.com/groups?q=RTOS+threads+history&hl=en&lr=&selm=Hifa2.51%24Z_4.163%40news.rdc1.wa.home.com&rnum=2


Evidence of tasks being a long-standing feature in VxWorks along with a
history of VxWorks that obviously predates Win32:


http://groups.google.com/groups?q=RTOS+threads+history&start=10&hl=en&lr=&selm=hjbCB6339.FIK%40netcom.com&rnum=19


Evidence that RTOSes are widely deployed, forming an entire long-standing
sizable industry:


http://groups.google.com/groups?q=RTOS+tasks+embedded+introduced&start=10&hl=en&lr=&selm=2047%40alcbel.be&rnum=14


Evidence that real-time operating systems had threads/tasks long before 1989:

http://groups.google.com/groups?q=RTOS+threads+earliest&hl=en&lr=&selm=33724547.14B%40expresslogic.com&rnum=4

"
> For academics, see also Rajkumar, Sha, Lehoczky, "An Experimental
> Investigation of Synchronization Protocols", Proc. 6th IEEE workshop on
> Real-Time Operating Systems and Software, p.11-17, May 1989. As far
> as I am aware, the earliest publication of the algorithm was in a paper
> by Lampson and Redhill in 1980. For a history of the research in this area,
> see Audsley, Burns, Davis, Tindell, and Wellings, "Fixed Priority Preemptive
> Scheduling: An Historical Perspective", Real-Time Systems 8(3),
> pp. 173-198 (1995).
"

-----------------------
By the way, to all people who think that Microsoft invented or popularized
technologies which appared in Windows95, Windows98, WindowsNT, Windows2000, or
WindowsXP:

Pre-emptive operating systems with multiple separate-address-space processes
were invented decades ago (not merely years ago in Win32 or even OS/2).
Pre-emptive multiprocess OSes were widely deployed by many computer vendors in
many product lines decades ago (not merely years ago in Win32 or even OS/2).
In fact at one time the largest single commercial vendor of a version of UNIX (a
preemptive multitasking operating system) was Microsoft themselves who sold
Xenix in the early 1980s. Microsoft sold Xenix to Santa Cruz Operation in the
first half of the 1980s, leaving Microsoft with a predominantly single-threaded
single-process operating system: MSDOS. In the early 1980s Gary Kildall's
Digital Research and Bill Gates's Microsoft were competing head to head on two
operating systems fronts: 1) DRI's CP/M versus Microsoft's DOS in the category
of single thread, single process operating systems for microcomputers and 2)
DRI's Microport UNIX versus Microsoft's Xenix in the category of preemptive
multiprocess operating systems.

Multiple threads-of-execution per shared address-space was invented
decades ago (not merely years ago in Win32). Multiple threads-of-execution
within one shared address-space was widely deployed in real-time embedded
systems decades ago (not merely years ago in Win32).

Graphical user interfaces on single-user computers were invented decades ago
in the 1970s (not in the mid1980s with the first release of MSWIN 1.0 running on
top of MSDOS). GUIs on single-user computers were widely deployed by Sun,
Apollo, Apple, and to some degree Xerox and others by the early 1980s.

Slava M. Usov

unread,
May 17, 2002, 2:55:09 PM5/17/02
to
"Hillel Y. Sims" <use...@phatbasset.com> wrote in message
news:C58F8.53567$ja.13...@news02.optonline.net...

Would you sleep better if it were a no? And you sound as if yes might be a
bad thing...

S


Slava M. Usov

unread,
May 17, 2002, 2:54:45 PM5/17/02
to
"Daniel Miller" <daniel...@tellabs.com> wrote in message
news:3CE53FA0...@tellabs.com...

> Excuse me!?! That is revisionist history! The real-time embedded
> software industry has been using multiple threads per shared address-
> space for multiple decades, long before the release of any Win32
> product.

Different story altogether. I said about multiple threads in multiple
address spaces, and most RTOSes had one address space, in which multiple
tasks may execute. For that reason, we may also quote MS-DOS as a
multithreaded system, in which it was an elementary matter to have multiple
tasks running [TSRs and device drivers]; unless you tried to perform IO
simultaneously, you could get away with that, and later on MS added some
undocumented or partly documented [I don't remember the details now] API
which would actually allow you to switch tasks and do some limited IO. This
was exploited by network redirectors and Windows, and is still being
exploited by Windows ME.

Actually I don't even care about who first invented and who first
implemented and whose's generically "bigger". :-)

I can take back the word "pioneer" if you are unhappy about that. But in
mainstream application programming threads had little appearance, if any,
before Win32. Most of the RDBMS on UNIX and VMS normally had multiple
processes and not multiple threads well into 90s. Same applies to other
types of network servers. I hear it was different on mainframes, though.

[...]

> UNIX System V Release 4.1MP (and its related bretheren UNIX SVR4.2,
> UnixWare, and Solaris 2.X) with UNIX International threads (i.e., before
> POSIX real-time extensions and before Win32's threads) shipped in 1992
> if I remember correctly.

Do not forget that most concepts of Win32 started to take shape in 1987 when
the work on OS/2 started. I have an ntexapi.h [posted by somebody on USENET
a few years ago] which contains declarations of most of NT's native API, in
particular, all of the synchronization primitives. Here is its header:

Copyright (c) 1989-1993 Microsoft Corporation

Module Name:

ntexapi.h

Abstract:

This module is the header file for the all the system services that
are contained in the "ex" directory.

Author:

David N. Cutler (davec) 5-May-1989

[end header]

That means they started working on that stuff at least in 1987, and so they
could only use things invented at least a couple of years before that, i.e.,
until 1985, as more or less accepted in the industry [or in the development
team even]...

To the rest of your points, the answers are identical.

S


Daniel Miller

unread,
May 17, 2002, 7:20:40 PM5/17/02
to
Slava M. Usov wrote:

> "Daniel Miller" <daniel...@tellabs.com> wrote in message
> news:3CE53FA0...@tellabs.com...
>
>
>> Excuse me!?! That is revisionist history! The real-time embedded
>>software industry has been using multiple threads per shared address-
>>space for multiple decades, long before the release of any Win32
>>product.
>>
>
> Different story altogether. I said about multiple threads in multiple
> address spaces, and most RTOSes had one address space, in which multiple
> tasks may execute.


Excuse me for being insistently correct, but you were definitely not
emphasizing anything interprocess/multiprocess-intraprocessor in any way. You
were talking about who pioneered commercially-deployed viable-in-the-marketplace
MT software designs & MT operating systems for MT software in general---i.e.,
software whose execution model is multiple threads-of-control within a shared
address-space. Those commercial pioneers would be the telecommunications
industry, the military contractor industry, and other embedded software
industries using commercial-off-the-shelf (COTS) real-time operating systems
(RTOSes), since the late 1970s & early 1980s who in turn based their work on
still earier pre-commercial research. Furthermore before using COTS RTOSes,
these industries used their own proprietary internally-developed RTOSes. [Many
companies in those industries today still use legacy proprietary RTOSes
developed during the 1970s or 1980s in some of their older products.]

Multithreaded software within one process running on a
single-process-per-processor operating system

is overwhelmingly the same as

multithreaded software within one process running on a
multiple-processes-per-processor operating system.

Same mutexes (a.k.a. binary semaphores).
Same Dijkstra/counting semaphores.
Same read-write locks.
Same asychronous (multi)producer-(multi)consumer message-queue delivery
mechanisms needed.
Same need to address in-coming asynchronous events & interrupts on some one
or more threads.
Same bugs due to two or more threads stepping on each other due to lack of
thread-synchronization or sufficient asynchronous unit-of-work hand-off via
message-queues.
Same bugs due to leaks of semaphore release/increment.
Same bugs due to leaks of mutex release.
Same research base.
Same solutions.
Same software designs.
Same problems with MT.
Same benefits deriving from MT.
Same priority-inversion considerations.


The only way which I consider them different with respect to
multithreadedness is that a few RTOSes do not have the following (whereas other
RTOSes do):
1) forking/spawning child processes (because RTOSes do not have processes
*plural*)
2) shared memory between different address-spaces (because RTOSes do not have
address-spaces *plural* until one considers the *interprocessor* case)
3) *interprocess-intraprocessor* thread-of-control synchronization (until one
considers the *interprocessor* case via networking protocols)
4) *interprocess-intraprocessor* asynchronous (multi)producer-(multi)consumer
message-queues for unit-of-work hand-off (until one considers the
*interprocessor* case via networking protocols)

Most people who work on MT software can go years without even realizing that
such interprocess-intraprocessor concepts exist to complement their
interthread/intraprocess concepts which they use every day.

> Actually I don't even care about who first invented and who first
> implemented and whose's generically "bigger".


This is not about one-upmanship competition. This is about how to stand on
the shoulders of giants who came beforehand in the multi-decade-old MT software
industry: the embedded real-time systems industry.

I encourage everyone to do a direct head-to-head feature-by-feature
comparison of VxWorks's or pSOS's multithreaded feature-set to Win32
multithreaded feature-set. If one is diligent, such an investigator will find
one common theme: most of the general-purpose operating-systems still to this
day emphasize

1) thread-*synchronization* (which tends to erode MT architectures down to
blocking-architecture status, not achieving sufficient concurrency)

over

2) *asynchronous* unit-of-work hand-off via (multi)producer-(multi)consumer
message-queues (which tend toward nonblocking architectures achieving far
greater concurrency).

There are still some things even after all these *decades* that the
general-purpose/hosted software world can learn from the embedded real-time
software world with respect to multithreaded software designs which we have
pioneered & honed over many years. That is, only if you admit that we exist in
the first place and have a multi-decade multithreaded knowledge-base built up in
our sector of the industry.

It is loading more messages.
0 new messages