possible typo in multithreading website

C

Comp1597

I have read the above from a multithreading in c++ tutorial:

BEGINNING OF QUOTE

Now imagine that we start a number of threads, all executing
workerThread(). If we have just one thread, doSomeWork() is going to
be executed the correct number of times (whatever sharedCounter starts
out at).

However, with more than one thread doSomeWork() will most likely be
executed too many times. Exactly how many times depends on the number
of threads spawned, computer architecture, operating system scheduling
and...chance. The problem arises because we do not test and update
sharedCounter as an atomic operation, so there is a period where the
value of sharedCounter is incorrect. During this time other threads
can pass the test when they really shouldn't have.

The value of sharedCounter on exit tells us how many extra times
doSomeWork() is called. With a single thread, the final value of
sharedCounter is of course 0. With multiple threads running, it will
be between 0 and -N where N is the number of threads.

Moving the update adjacent to the test will not make these two
operations atomic. The window during which sharedCounter is out of
date will be smaller, but the race condition remains. An illustration
of this non-solution follows:

Listing 2. Still a race condition

void* workerThread(void*)
{
while(sharedCounter > 0)
{
--sharedCounter;
doSomeWork();
}

The solution is to use a mutex to synchronise the threads with respect
to the test and update. Another way of saying this is that we need to
define a critical section in which we both test and update the
sharedCounter. The next section introduces mutexes and solves the
example race condition.

END OF QUOTE.

I believe that the correct signature of workerThread is void
workerThread(void) rather than void* workerThread(void*)

Am I correct?

Any other comments on the webpage are welcome.

Thanks.
 
C

Comp1597

On Sun, 12 Apr 2009 04:28:47 -0700, Comp1597 wrote:

[snip]


I believe that the correct signature of workerThread is void
workerThread(void)   rather than void* workerThread(void*)
Am I correct?

If you mean pthread callbacks, then NO, you are wrong.

$ man pthread_create

Thanks. The quoted article is from paulbridger.net and it claims to
teach c++ multithreading to a relative newbie (obviously a total
newbie wouldn't be learning multithreading.)
Anyway, I believe that I'm an ideal reader for that site. And it
wasn't (and isn't) apparent why void pointers are needed in the above
code segment. Could anyone guide me to a good free e-resource on c++
multithreading that explains these things better?

Thanks again.
 
J

Jerry Coffin

[ ... ]
Thanks. The quoted article is from paulbridger.net and it claims to
teach c++ multithreading to a relative newbie (obviously a total
newbie wouldn't be learning multithreading.)
Anyway, I believe that I'm an ideal reader for that site. And it
wasn't (and isn't) apparent why void pointers are needed in the above
code segment. Could anyone guide me to a good free e-resource on c++
multithreading that explains these things better?

It uses pointers to void so you can actually pass a pointer to some
arbitrary data. Likewise, the return value allows returning some
arbitrary data of your choice.
 
J

James Kanze

I have read the above from a multithreading in c++ tutorial:
BEGINNING OF QUOTE

[...]
Listing 2. Still a race condition
void* workerThread(void*)
{
while(sharedCounter > 0)
{
--sharedCounter;
doSomeWork();
}
The solution is to use a mutex to synchronise the threads with
respect to the test and update. Another way of saying this is
that we need to define a critical section in which we both
test and update the sharedCounter. The next section introduces
mutexes and solves the example race condition.
END OF QUOTE.
I believe that the correct signature of workerThread is void
workerThread(void) rather than void* workerThread(void*)

It depends. If the function is the one passed to
pthread_create, then the correct signature in C++ is:

extern "C" void* workerThread( void* ) ;

Nothing else should pass the compiler. (G++ is buggy here, and
accepts the code without the `extern "C"'.)

For Windows, it should be:

DWORD WINAPI workerThread( __in LPVOID ) ;

(I'm not sure what all those macros mean: DWORD sounds like a
long long, WINAPI is probably some implementation extension
controling the linkage---the equivalent of `extern "C"' in
standard C++, and LPVOID a long pointer to void, except that I
didn't think that Windows supported long (48 bit) pointers.)
 
J

James Kanze

[ ... ]
Thanks. The quoted article is from paulbridger.net and it
claims to teach c++ multithreading to a relative newbie
(obviously a total newbie wouldn't be learning
multithreading.) Anyway, I believe that I'm an ideal reader
for that site. And it wasn't (and isn't) apparent why void
pointers are needed in the above code segment. Could anyone
guide me to a good free e-resource on c++ multithreading
that explains these things better?
It uses pointers to void so you can actually pass a pointer to
some arbitrary data. Likewise, the return value allows
returning some arbitrary data of your choice.

That's the motivation for the additional pointer in the API. In
the posted code, the reason for the pointer was simply that the
API requires it in the signature of the function.

Just as it requires the function to be extern "C", so there was
an error in the example code:).
 
M

Michael Mol

Pete Becker <[email protected]> kirjutas:





Likewise, DWORD is a leftover from 16-bit processor days, where WORD
(machine natural processing unit) was 16-bit, and double word (DWORD)
hence 32-bit. Never mind that the processor word has meanwhile grown to
64-bit in common Windows platforms.

And they don't have a QWORD typedef for unsigned 64-bit integers, it's
a much less convenient ULONGLONG.
 
J

James Kanze

Likewise, DWORD is a leftover from 16-bit processor days,
where WORD (machine natural processing unit) was 16-bit, and
double word (DWORD) hence 32-bit. Never mind that the
processor word has meanwhile grown to 64-bit in common Windows
platforms.

Except that I know DWORD from back when the largest Intel
processor was 8 bits, and Microsoft only make language tools
(Basic, Fortran, etc.). It's standard IBM terminology (and thus
widespread): BYTE: 8 bits, HWORD (or half word): 16 bits, WORD:
32 bits, and DWORD: 64 bits. (But in this case, I think it's
Intel which first broke with tradition, and not Microsoft. The
8080 assembler only had bytes and words.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top