|
|
 | | From: | mathew | | Subject: | NSThreads and loops in methods | | Date: | 27 Nov 2004 03:05:33 -0800 |
|
|
 | As a reply to this post: http://groups.google.co.nz/groups?hl=en&lr=&safe=off&selm=8jsfhl%246gg%241%40nnrp1.deja.com
I've also had a problem as a Cocoa/ObjC newbie in finding examples of using NSThreads and making sense of the documentation and examples posted on the web.
As a starting point I wanted to develop a very simple class that will print out a list of numbers 0 to 9. Without threads the numbers 0-9 will be printed sequentially 012..789012..789 and if threaded the numbers would be printed 001122..778899
It seemed like a good starting point for Thread programming and as an easy introduction to ObjC, but it proved to be more difficult that expected.
the following files I've managed to get this behaviour, but I'm not sure if it's the best practice, but I'll post them here in case they are any help to other newbies.
Perhaps some more experienced developers could point out what I could have done better - or perhaps show how to change the code so that communication can occue between the Threads, which is the next step that I will attempt.
The header file has been omitted for space...
**** fraction.m ****
#import "Fraction.h" #import
@implementation Fraction -(void) print {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int i; for (i = 0; i < 10 ; i++){ printf( "%i\n", i); [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; } [pool release]; } @end
**** main.m ****
#import #import "Fraction.h"
int main( int argc, const char *argv[] ) { // create a new instance Fraction *frac1 = [[Fraction alloc] init]; Fraction *frac2 = [[Fraction alloc] init]; [NSThread detachNewThreadSelector: @selector(print) toTarget: frac1 withObject: nil]; [NSThread detachNewThreadSelector: @selector(print) toTarget: frac2 withObject: nil]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int i; for ( i=0; i<1; i++){ [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]; } [pool release]; return 0; }
|
|
 | | From: | Michael Milvich | | Subject: | Re: NSThreads and loops in methods | | Date: | 27 Nov 2004 17:38:42 -0800 |
|
|
 | mathew.sanders@gmail.com (mathew) wrote in message news:<79b33e9f.0411270305.1d7b111f@posting.google.com>...
> As a starting point I wanted to develop a very simple class that will > print out a list of numbers 0 to 9. Without threads the numbers 0-9 > will be printed sequentially 012..789012..789 and if threaded the > numbers would be printed 001122..778899 > > It seemed like a good starting point for Thread programming and as an > easy introduction to ObjC, but it proved to be more difficult that > expected.
As you have discovered your seemingly simple problem is not that simple. To understand why we have to look at how the operating system manages threads. For now only consider a single processor computer. A processor can only run a single thread of execution at a time. In order to run multiple processes and threads, a modern operating system will periodically interrupt the current thread of execution and switch the CPU to a different thread of execution. This interruption is called a context switch. During this switch the os also does some work to switch the current memory space from the old process to the new process. In order to give the illusion that multiple threads are executing at the same time, the OS switches rapidly between the running threads, giving each thread a small amount of time to run.
So with your sample problem where you want to print out 0-9 from two different threads at the same time, is not possible without an addition method to synchronize the threads. This is because thread 1 will run, and then thread 2 will run after either thread 1 has finished, or the OS decides that thread 1 has been executing long enough and kicks it off the processor to allow thread 2 to run. In this case your computer can print out 0-9 fast enough that thread 1 is finishing its task before the os interrupts it to schedule thread 2. So you will almost always see 0-9 and then 0-9 printed out. If you were to change that to print from 0-1000, you will probably get interrupted a few times and the numbers will be interwoven in groups, so you will get something like 0-50, 0-70, 51-200, 71-150, etc... Depending on the scheduler used, it will probably be impossible to predict how much time a thread will get to execute. So you should get a different pattern of interweaving each time you run the program.
In order to do what you want you need to synchronize the threads. So that after printing a number thread 1 will wait for thread 2 to do the same thing, before trying to print out the second number (and vis versa, since you don't know which thread will go first). In order to do this you should read up on how Cocoa does locking at http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/index.html or by looking at any other book about threading.
Michael
|
|
|