discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to terminate another thread?


From: Stefan Urbanek
Subject: Re: How to terminate another thread?
Date: Wed, 24 Jul 2002 00:16:44 +0200

Hello David,

First, thank you for your time and naswer.

David Ayers wrote:
> 
> Hello Stefan,
> 
> I'm not quite sure if I understand what you need but maybe if you clairify a 
> couple ot things I might be able to help. But let me try anyway:
> 
> In the code you provided you seem to give EVERY Object the ability to supply 
> a proxy of itself running (accetping messages) in a different thread! Wow, 
> ahm are sure you want to do that? Ehm. Ok, well first to the question:
> 
Well, I need it for several objects of different classes and they may not have
common ancestor, only NSObject. I want the objects to be something like
'Actors' - handling asynchronous (oneway) messages. To handle oneway messages
withot creating my own mechanisms I am using  threads. In most operating
systems, including linux, threads are expensive, but is there any other
option?

When the object is not needed anymore or when it is going to be replaced, it
is released. When the object is released, I want the thread in which I am
handling asynchronous messages for the object to be terminated. AFAIK The
messages are dispatched in NSRunloop, so I need to break the runloop.

> What you seem to be doing with proxyInNewThread is to allow any object to 
> start a new thread, register itself back in the thread which started it to 
> update the global dictionary (hopfully you only use proxyInNewThread in the 
> one specific thread othewise you sould guard your global dictionary) and then 
> run the runloop indefinatly. Now if I interpret your question correctly, you 
> want the runloop to stop procesing, once there are no more messages to 
> process (input sources).
> 

I thing, that NSDictionary is thread-safe, isn't it? I might be wrong. Bu this
code needs locking (i forgot that):
    request = [NSNumber numberWithInt:requestID];
    requestID ++;

And, yes, I need to stop the run-loop, in this case. Or is there another way
of handling asynchronous messages than using runloop?

> Well I think all you have to do is use a different way of running the runloop 
> in _establishThreadConnectionUsingParameters:
> 
> use runUntilDate: providing a maximum timeout (at worst [NSDate 
> distantFuture]) and this should return once all messages are processed and 
> the thread shoud continue (and exit) normally. You might need some additional 
> mechanism to keep it running until the first message has arrived, but I'm not 
> sure on that.
> 

Problem is, that there is no maximum timeout. One of the possible ways may be
running the runloop with runUntilDate:some_near_furure in a loop and checking
womehow, if it has to be terminated.

Ok, I have modified the code like this:

in _establishThreadConnectionUsingParameters I have changed:

...
    threadDict = [[NSThread currentThread] threadDictionary];
    [threadDict setObject:self forKey:@"ThreadOwner"];

    NSDebugLog(@"Connection established");

    while( ![[threadDict objectForKey:@"ThreadTerminationRequest"]
isEqual:@"YES"] )
    {
        [[NSRunLoop currentRunLoop] runUntilDate:
                            [NSDate dateWithTimeIntervalSinceNow: 2]];
    }

    [threadDict removeObjectForKey:@"ThreadOwner"];

    NSLog(@"Thread terminated");
...

and added:

- (void)terminateProxyThread
{
    NSThread     *thread = [NSThread currentThread];
    NSDictionary *dict = [thread threadDictionary];
    if([dict objectForKey:@"ThreadOwner"] == self)
    {
        NSLog(@"Thread termination request");
        [dict setObject:@"YES" forKey:@"ThreadTerminationRequest"];
    }
    else
    {
        NSLog(@"Could not terminate proxy thread, "
              @"because this object is not an owner");
    }
}

it seems to work, but I am not sure if it is the right way.

> BUT! I believe what you are doing is EXTREMLY dangerous. Especially if you 
> think of using this proxy for arbitrary objects (Or why is it a category of 
> NSObject?) Make sure all access to your instance variabels of the objects you 
> are "running" in the new thread are guarded corrctly by locks.

Sure, I am using locks where it is necessary.

> 
> Nicola pointed me to a very interesting uRL about Double-Checked-Locking. 
> I'll forwarded privatly once I get back home. I can't access it from where I 
> am right now.
> 

Thanks.

> I prefer to use seperate Objects in a DO environment to actually insure that 
> an instance can only execute messages in one thread. Actually I go so far as 
> to have instances of different classes on either end of an connection. To set 
> them up I pretty much follow the docs 
> http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/DistrObjects/index.html
>  by passing the ports in a dictionary to a class method with is invoked by 
> the detach, which then allocs/inits the "Remote Object". Then the "Remote 
> Object" can then ask for a proxy of an object in the orignal thread if it 
> needs it. Then it remains clear which implemtations are executed in which 
> thread and locking can be avioded since the instance variables aren't shared 
> by the threads. But maybe you have reason not do this. And remember to guard 
> globals in anycase. (And as have just recently realized, static local 
> variables must be guarded just as globals in this case.)


I was following "Forming Connections Between Threads" at
http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/Multithreading/index.html


Thanks again,

Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]