views:

241

answers:

3

First off I'm not that familiar with using threads and i'm learning on the fly. I have an array that is being used in thread a and being populated in thread b. What I want to do is find the best practice for waiting for the array to be populated from thread b before using it in thread a.

+2  A: 

I haven't used Objective C but what you're looking for is a Condition Lock. This is a type of lock (mutex) that prevents threads from accessing locked data but keeps a queue of all the threads that asked for permission (often using a semaphore). When the data becomes unlocked, the Condition Lock automatically wakes up the requesting threads.

In your case, the array will be locked by thread B while its being populated. When thread A tries to access the array, it will yield because thread B currently holds the lock. When thread B is finished, it will see that thread A tried to access the array while it was locked and wake up thread A. Thread A can then safely access the array.

Here's the first result after a google search for Condition Locks in Objective C. It's about the iPhone API, but might be useful nonetheless:

http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW4

Kai
+3  A: 

You can either copy the array in the reading thread so that it does not change while you read it, or you can @synchronize the access to the array:

- (void) writer
{
    @synchronized(theArray)
    {
        [theArray addObject:foo];
    }
}

- (void) reader
{
    @synchronized(theArray)
    {
        for (id item in theArray)
            [item …];
    }
}
zoul
...but before you do this, read the apple docs on thread locking. They outline some very subtle defects you can generate.
Roger Nolan
+1  A: 

The answer depends somewhat on what you are doing with the array contents.

To some degree, the question does not make a lot of sense - if thread a has to wait until the entire array is populated in thread b, then why not just do the populating work in thread a? What else is it doing while waiting for the array?

Alternatively, if thread a can make forward progress as it receives each element of the array, then it may make more sense to pass each received array entry from thread b to thread a as they are created. In that case you effectively have a queue, which is a common producer/consumer pattern for threaded work - thread b fills up a queue which thread a reads from.

See the "Using an NSConditionLock Object" section of the link Kai posted for an example producer/consumer lock.

Peter N Lewis