Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< Previous PageNext Page > Hide TOC

Creating a Thread

Creating low-level threads is relatively simple. In all cases, you must have a function or method to act as your thread’s main entry point and you must use one of the available thread routines to start your thread. The following sections show the basic creation process for the more commonly used thread technologies. Threads created using these techniques inherit a default set of attributes, determined by the technology you use. For information on how to configure your threads, see “Configuring Threads.”

In this section:

Using NSThread
Using POSIX Threads
Using NSObject to Spawn a Thread
Using Other Threading Technologies


Using NSThread

There are two ways to create a thread using the NSThread class:

Both techniques create a detached thread in your application. A detached thread means that the thread’s resources are automatically reclaimed by the system when the thread exits. It also means that your code does not have to join explicitly with the thread later.

Because the detachNewThreadSelector:toTarget:withObject: method is supported in all versions of Mac OS X, it is more frequently used than the other technique. To detach a new thread, you simply provide the name of the method (specified as a selector) that you want to use as the thread entry point along with the object that defines that method and any data you want to pass to the thread. The following example shows a basic invocation of this method that spawns a thread using a custom method of the current object.

[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];

Prior to Mac OS X v10.5, you used the NSThread class primarily to spawn threads. Although you could get an NSThread object and access some thread attributes, you could only do so from the thread itself after it was running. In Mac OS X v10.5, support was added for creating NSThread objects without a running thread. This support made it possible to get and set various thread attributes prior to starting the thread. It also made it possible to use that thread object later to refer to the running thread.

The simple way to initialize an NSThread object is to use the initWithTarget:selector:object: method. This method takes the exact same information as the detachNewThreadSelector:toTarget:withObject: method and uses it to initialize a new NSThread instance. It does not start the thread, however. To start the thread, you call the thread object’s start method explicitly, as shown in the following example:

NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                        selector:@selector(myThreadMainMethod:)
                                        object:nil];
[myThread start];

Note: An alternative to using the initWithTarget:selector:object: method is to subclass NSThread and override its main method. You would use the overridden version of this method to implement your thread’s main entry point. For more information, see the subclassing notes in NSThread Class Reference.

If you have an NSThread object whose thread is currently running, one way you can send messages to that thread is to use the performSelector:onThread:withObject:waitUntilDone: method of almost any object in your application. Support for performing selectors on threads (other than the main thread) was introduced in Mac OS X v10.5 and is a convenient way to communicate between threads. The messages you send using this technique are executed directly by the other thread as part of its normal run-loop processing. (Of course, this does mean that the target thread has to be running in its run loop, but that is a relatively straightforward matter; see “Run Loop Management.”) You may still need some form of synchronization when you communicate this way, but it is still simpler than setting up communications ports between the threads.

Note: Although good for occasional communication between threads, you should not use the performSelector:onThread:withObject:waitUntilDone: method for time critical or frequent communication between threads.

For a list of other thread communication options, see “Setting the Detached State of a Thread.”

Using POSIX Threads

Mac OS X provides C-based support for creating threads using the POSIX thread API. This technology can actually be used in any type of Mac OS X application (including Cocoa applications) and might be more convenient if you are writing your software for multiple platforms. The POSIX routine you use to create threads is called, appropriately enough, pthread_create.

Listing 3-1 shows two custom functions for creating a thread using POSIX calls. The LaunchThread function creates a new thread whose main routine is implemented in the PosixThreadMainRoutine function. The new thread is created as a detached thread in the following example. The default attribute set for POSIX results in the creation of joinable threads. Marking the thread as detached gives the system a chance to reclaim the resources for that thread immediately when it exits.

Listing 3-1  Creating a thread in C

#include <assert.h>
#include <pthread.h>
 
// The thread entry point routine.
void* PosixThreadMainRoutine(void* data)
{
    // Do some work here.
 
    return NULL;
}
 
void LaunchThread()
{
    // Create the thread using POSIX routines.
    pthread_attr_t  attr;
    pthread_t       posixThreadID;
 
    assert(!pthread_attr_init(&attr));
    assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
 
    int     threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, NULL);
 
    assert(!pthread_attr_destroy(&attr));
    if (threadError != 0)
    {
         // Report an error.
    }
}

If you add the code from the preceding listing to one of your source files and call the LaunchThread function, it would create a new detached thread in your application. Of course, new threads created using this code would not do anything useful. The threads would launch and almost immediately exit. To make things more interesting, you would need to add code to the PosixThreadMainRoutine function to do some actual work. To ensure that a thread knows what work to do, you can pass it a pointer to some data at creation time. You pass this pointer as the last parameter of the pthread_create function.

To communicate information from your newly created thread back to your application’s main thread, you need to establish a communications path between the target threads. For C-based applications, there are several ways to communicate between threads, including the use of ports, conditions, or shared memory. For long-lived threads, you should almost always set up some sort of interthread communications mechanism to give your application’s main thread a way to check the status of the thread or shut it down cleanly when the application exits.

Using NSObject to Spawn a Thread

In Mac OS X v10.5 and later, all objects have the ability to spawn a new thread and use it to execute one of their methods. The performSelectorInBackground:withObject: method creates a new detached thread and uses the specified method as the entry point for the new thread. For example, if you have some object (represented by the variable myObj) and that object has a method called doSomething that you want to run in a background thread, you could could use the following code to do that:

[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];

The effect of calling this method is the same as if you called the detachNewThreadSelector:toTarget:withObject: method of NSThread with the current object, selector, and parameter object as parameters. The new thread is spawned immediately using the default configuration and begins running. Inside the selector, you must configure the thread just as you would any thread. For example, you would need to set up an autorelease pool (if you were not using garbage collection) and configure the thread’s run loop if you planned to use it. For information on how to configure new threads, see “Configuring Threads.”

Using Other Threading Technologies

Although the POSIX routines and NSThread class are the recommended technologies to use for creating low-level threads, Mac OS X does include other C-based technologies. Of these, the only other one you might consider using is Multiprocessing Services, which is itself implemented on top of POSIX threads. Multiprocessing Services was developed originally for earlier versions of Mac OS and was later made available for Carbon applications in Mac OS X. If you have existing code that uses this technology, you can continue to use it, although you should also consider porting your thread-related code to POSIX.

For information on how to use Multiprocessing Services, see Multiprocessing Services Programming Guide.



< Previous PageNext Page > Hide TOC


Last updated: 2008-02-08




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice