Re: How can I stop running loop?
Re: How can I stop running loop?
- Subject: Re: How can I stop running loop?
- From: Shawn Erickson <email@hidden>
- Date: Thu, 2 Dec 2004 08:23:17 -0800
On Dec 1, 2004, at 8:48 PM, Mai Bui wrote:
Thanks a lot Shawn.
I think you did not get my reply, so I resend it now.
To answer your questions:
1. It acquire acoustic data (temp, density, conductivity, etc...)
2. These data are fed to serial port and my application reads them from it constantly. No block neither poll.
I wrote a small test. It has "stop" and "run" button (NSButton). The user will click on "run", it will create 2 thread (run, stop). For test, in run() has a while loop. In stop(), if the user click on it. It will turn the Doneflag on which is invoke later from run, it will stop app. But.... I do not know how to check the status of this stop button.
Can you or someone give me a hint?
Sure but you should look up programming resources on how to do multithreaded applications.
The following is a reworked example (not tested and written quickly) that should do what you want. Basically you UI events come into you applications main thread (assuming you are using a standard NSApplication) and if the user clicks on the start button you get the "runButton:" IB action called. This starts up the worked thread as needed. This worker thread runs and periodically check to see if it has been asked to stop. Once the work thread stops it calls back onto the main thread to let the UI elements know that is has stopped running. Additionally I show one possible way of updating UI element with status from the worker thread as it runs.
The way I communicate between threads in this example is by using a simple boolean that the main thread sets when asked to start/stop, etc. and the worker thread checks periodically. To insure that the work thread reads in the latest value from system memory and that the main thread wrote out the latest value to system memory I have surrounded access to that instance variable with locking constructs. Locking constructs trigger a memory barrier not just provide the ability to prevent concurrent modification (in this example the later really isn't needed). The memory barrier insures proper ordering so the latest value is read in for example by the gather.
We could also have marked the stopGathering as volatile which would gotten the compiler to generate code that would always access the value from main memory (in most compilers, be careful on how the support volatile). Doing this we wouldn't need the locking constructs but I usually prefer to do the way I outlined because it is more specific on intent, better setup for future modification to the communication between threads, and to avoid the possible pit falls related to performance that volatile can cause (it makes every access / write to that variable hit main memory every time).
Also consider using an NSConditionLock to both provide the locking/memory barrier as well as the boolean (condition) itself. See the following for examples: <http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/Tasks/usinglocks.html>
FYI to use "
synchronized" you need to enable Objective-C exceptions in the project settings and be using 10.3 or later.
-----
- (id)init
{
self = [super init];
if (self != nil) {
//gatherLock = [[NSLock alloc] init];
NSLog(@"Init\n");
}
return self;
}
- (void)dealloc
{
//[gatherLock release]; gatherLock = nil;
}
- (id)sender
{
NSLog(@"Pressed start button\n");
if (gatherIsRunning) return; // just in case we get called... don't want to start another thread, etc.
gatherIsRunning = YES;
[startButton setEnabled:NO]; // disable the run button
[stopButton setEnabled:YES]; // enable the stop button
stopGathering = NO; //just to make sure it is set as expected
// fire up secondary thread to do the work needed...
[NSThread detachNewThreadSelector: @selector(gatherData) toTarget:self withObject:nil];
}
- (id)sender
{
NSLog(@"Pressed stop button\n");
[stopButton setEnabled:NO]; // disable the stop button
//For the following gatherLock is just a standard NSLock
//that is alloc/inited in your init method and released in dealloc
//[gatherLock lock];
//stopGatheringData = YES;
//[gatherLock unlock];
// You can use the above lock based code or if you are targeting 10.3 and later the below...
self) {
stopGathering = YES;
}
//In reality as this example is codeed you don't need to do the above locking/synchronzing
//because the comminucation is one way and not in a looping construct
//that could delay the writing stopGatheringData value to memory...
}
- (void)stoppedGathering
{
NSLog(@"Gather thread has reported it stopped\n");
gatherIsRunning = NO;
[startButton setEnabled:YES]; // enable the run button
[stopButton setEnabled:NO]; // disable the stop button
}
- (void)gatherData
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Gather started\n");
// setup as needed...
int i;
for (i=0; i<5000; i++) //or while(1) to go forever until stopped, error, no more data, etc.
{
// For the folloing gatherLock is just a standard NSLock
// that is alloc/inited in your init method and released in dealloc
// [gatherLock lock];
// if (stopGatheringData) {
// [gatherLock unlock];
// break;
// }
// [gatherLock unlock];
// You can use the above lock based code or if you are targeting 10.3 and later the below...
self) {
if (stopGathering) {
NSLog(@"Gather thread detected stop request\n");
break;
}
}
// DO A UNIT OF WORK HERE...
// The smaller the unit of work the faster this thread will exit when requested by the user
// For the following only do it once every few seconds, no need to blast the UI and user with updates
// If you want to report status, etc. out to UI objects it is best to do that on the main thread
[statusText performSelectorOnMainThread:@selector(insertText:)
withObject:[@"example result"]
waitUntilDone:NO];
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
// clean up as needed...
[self performSelectorOnMainThread:@selector(stoppedGathering)
withObject:nil
waitUntilDone:NO];
NSLog(@"Gather stopped\n");
[pool release];
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden