In general, you should avoid terminating a task directly. Instead, you should let the task exit normally, either because it has finished its assigned work, or because you posted a quit notification. Doing so allows the task to dispose of any resources or structures it may have allocated. In addition, in Mac OS X, MP tasks may use additional system resources that do not expect to have the task abruptly terminated.
If you must terminate a task, you should call the function MPTerminateTask, ideally when the task is blocked waiting on an MP synchronization construct (queue, event, semaphore, or critical region). Doing so deletes the task, but you are still responsible for disposing of any memory you may have allocated for the task. In addition, because the tasks run asynchronously, the task may not actually terminate until sometime after the MPTerminateTask function returns. Therefore, you should not assume that the task has terminated until you have received a termination message from the notification queue you specified in the function MPCreateTask. See the discussion of MPTerminateTask in Multiprocessing Services Reference in Carbon Process Management documentation for additional considerations.
Listing 2-3 shows how you might terminate the tasks created in Listing 2-1.
Listing 2-3 Terminating tasks
void StopMPTasks(void) |
{ |
UInt32 i; |
if (myTaskData != NULL) |
{ |
for (i = 0; i < numProcessors; i++) |
{ |
if (myTaskData[i].TaskID != NULL) |
{ |
MPTerminateTask(myTaskData[i].TaskID, noErr); |
MPWaitOnQueue(notificationQueue, NULL, NULL, NULL, |
kDurationForever); |
} |
if (myTaskData[i].fRequestQueue != NULL) |
MPDeleteQueue(myTaskData[i].RequestQueue); |
if (myTaskData[i].fResultQueue != NULL) |
MPDeleteQueue (myTaskData[i].ResultQueue); |
} |
if (notificationQueue != NULL) |
{ |
MPDeleteQueue (notificationQueue); |
notificationQueue = NULL; |
} |
DisposePtr((Ptr)myTaskData); |
myTaskData = NULL; |
} |
} |
The StopMPTasks function iterates through all the task data structures that were created in CreateMPTasks and checks for those with valid task IDs. It then calls the function MPTerminateTask for each valid task ID.
After making the termination call, StopMPTasks then waits for a message to appear on the notification queue indicating that the task has in fact been terminated. It does so by waiting continuously on the notification queue until the termination message arrives. It then clears the task ID and disposes of the queues allocated for the task.
Note: If you call MPWaitOnQueue from a cooperative task, you should specify only the kDurationImmediate wait time. You must use a while loop that continuously calls MPWaitOnQueue until the termination message appears in the notification queue. Doing so also allows you to process events that may occur between calls. For additional information, see “Synchronizing and Notifying Tasks”.
After terminating all the existing tasks, StopMPTasks then deletes the notification queue and disposes of the task data structures.
Last updated: 2007-10-31