knowledge-database (beta)

Current group: comp.lang.objective-c

NSThreads and loops in methods

NSThreads and loops in methods  
mathew
 Re: NSThreads and loops in methods  
Michael Milvich
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
   

Copyright © 2006 knowledge-database   -   All rights reserved