Article View: comp.os.os2.programmer
Article #1540Re: Horses!
From: Alan Ballard
Date: Fri, 28 Sep 1990 06:01
Date: Fri, 28 Sep 1990 06:01
61 lines
3168 bytes
3168 bytes
In article <90270.152726TURGUT@TREARN.BITNET> TURGUT@TREARN.BITNET (Turgut Kalfaoglu) writes:
>... Here is the curiosity: if I put a
>DosSleep(0L) in the main()'s loop where the beginthread is called five
>times to create the five horses, everything is fine. If I remove that,
>five horses are created, but they each receive the same index number (5),
>and they move together too! (so only one horse appears on display). It
>roughly looks like this:
>
>for (j=0;j<5;j++) {
> if (_beginthread(horse,NULL,4096,&j) == 0) {
> printf("Error");
> exit(1);
> }
> DosSleep(0L);
>}
>I remove the DosSleep and it no longer works!
>
>Any ideas? Is it a bug in OS/2 1.1 that got corrected with 1.2 ?
Nope, its a bug in your version of the program. You're passing the address
of the variable j. There are no guarantees about when the new processes
will actually get to execute. Without the DosSleep, the main thread
keeps running, for a while, and by the time the other threads
get to pick up the parameter it has already changed back in the main
thread. DosSleep with a parameter of zero gives the threads a chance
to run for one time slice, so they pick up the value at that time and each
get the appropriate value.
To do this properly, you need to either pass the parameter by value, as it
was in the original version or use semaphores to properly synchronize
the startup so that each thread gets its parameter before the main
thread goes on to start the next.
Norton/LaFore's version of this program contains a C coding bug in the
stack initialization, by the way (which may be the reason you switched
to _beginthread?)
The line
stkptr = (int far *)malloc(STACK_SIZE) + STACKSIZE;
should replaced with some variant of
stkptr = (int far *)((char far *)malloc(STACK_SIZE) + STACK_SIZE);
I've found Norton/LaFore good for getting the basic idea of the OS/2
kernel services, but it is rather casual about IPC issues in many
of the multi-threaded processes. The requires synchronization is only
done in places where it is the subject of the example; lots of other
critical sections are really needed to make the programs
behave as described.
>Also I noticed that if the main() ends, even with DosExit(0,0),
>all threads are killed, which is contrary to Peter Norton's book..
I seem to recall this was a change between 1.0 and 1.1 (or maybe
between 1.1 and 1.2). When the main thread exits, all threads exit.
Alan Ballard | Internet: ballard@ucs.ubc.ca
University Computing Services | Bitnet: USERAB1@UBCMTSG
University of British Columbia | Phone: 604-228-3074
Vancouver B.C. Canada V6R 1W5 | Fax: 604-228-5116
Technical Details
Message-ID:
<9778@ubc-cs.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!van-bc!ubc-cs!cheddar.ucs.ubc.ca!ballardReferences:
<90270.152726TURGUT@TREARN.BITNET>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!van-bc!ubc-cs!cheddar.ucs.ubc.ca!ballard From: ballard@cheddar.ucs.ubc.ca (Alan Ballard) Newsgroups: comp.os.os2.programmer Subject: Re: Horses! Message-ID: <9778@ubc-cs.UUCP> Date: 28 Sep 90 06:01:45 GMT References: <90270.152726TURGUT@TREARN.BITNET> Sender: news@cs.ubc.ca Reply-To: ballard@cheddar.ucs.ubc.ca (Alan Ballard) Organization: UBC Computing Centre, Vancouver, B.C., Canada Lines: 61