Как объединить потоки в Objective C без использования делегатов / обратного вызова? - PullRequest
4 голосов
/ 01 сентября 2010

Есть ли чистый способ объединения потоков в Objective C, похожий на "Thread.join" в Java? Я нашел метод executeSelector: onThread: withObject: waitUntilDone: но ограничением этого является то, что я не могу вызвать «блокировку» в другой строке, потому что я хочу сделать что-то вроде этого:

[dispatch Thread A];
[process something on main thread];
[wait for Thread A to finish before proceeding];

Заранее спасибо.

Ответы [ 5 ]

12 голосов
/ 01 сентября 2010

Я не знаю ни одного API-интерфейса Cocoa, чтобы сделать это, но с NSThread это было бы не так уж сложно сделать, довольно легко сделать с блокировкой и еще проще с Grand Central Dispatch.

NSThread

NSThread * otherThread = [[NSThread alloc] initWithTarget:self selector:@selector(methodToPerformInBackground:) object:aParameter];
[otherThread start];

//do some stuff

while ([otherThread isFinished] == NO) {
  usleep(1000);
}
[otherThread release];

NSLock

NSLock * lock = [[NSLock alloc] init];

//initiate the background task, which should immediately lock the lock and unlock when done

//do some stuff

[lock lock]; //this will pause until the background stuff unlocks
[lock unlock];
[lock release];

Grand Central Dispatch

dispatch_group_t myGroup = dispatch_group_create();
dispatch_group_async(myGroup, dispatch_get_global_queue(), ^{
  //stuff to do in the background
});

//do some stuff

dispatch_group_wait(myGroup, DISPATCH_TIME_FOREVER);
dispatch_release(myGroup);
4 голосов
/ 01 сентября 2010

NSConditionLock - ответ на мой вопрос, извините, Дэйв Делонг, но я не могу использовать:

  1. "while ([otherThread isFinished] == НЕТ)" - потому что мне нужна быстрая непрерывная обработка и я не могу спать.

  2. NSLock - потому что, как вы сказали, «инициировать фоновую задачу, которая должна немедленно заблокировать блокировку и разблокировать, когда это будет сделано», это не решение, потому что я попробовал это сделать, и мы не уверены, будет ли подпроцесс выполняться последним до разблокировки блокировки -релиз в основном потоке, в итоге я получаю случайные ошибки.

  3. Grand Central Dispatch - поскольку он доступен только в IOS4 и Snow Leopard 10.6, я использую более низкую версию.

Но ваш ответ дал мне идею и большое спасибо за это, поэтому я просто "поднял" вас.

Я закончил тем, что сделал:

#define T_START 0
#define T_FINISHED 1
-(void) updateVerticalScopeBackground: (id) aParam {   
[lockForThread lock];   
NSAutoreleasePool *pool = [NSAutoreleasePool new];   
//do something
[pool release];   
[lockForThread unlockWithCondition:T_FINISHED];  
}


-(void) sumFunc { 
  lockForThread = [[NSConditionLock alloc]
                                   initWithCondition: T_START];
  NSThread* updateVerticalScope = [[NSThread alloc] initWithTarget:self selector:@selector(updateVerticalScopeBackground:) object:nil];
  [updateVerticalScope start];

  //do some processing

  [lockForThread lockWhenCondition:T_FINISHED];   
  [lockForThread unlockWithCondition:T_FINISHED];   
  [lockForThread release]; 
}
3 голосов
/ 01 сентября 2010

Вы можете использовать NSCondition сигнал / ожидание.

1 голос
/ 01 сентября 2010

Вы никогда не хотите, чтобы ваш основной поток был заблокирован в ожидании другого потока.По крайней мере, вы этого не делаете ни в одном приложении с пользовательским интерфейсом, потому что, если основной поток заблокирован, ваше приложение будет заморожено.

Было бы гораздо лучше, если бы основной поток запустил фоновый поток, сделайтедругие вещи, которые нужно сделать, а затем вернуться к циклу выполнения.Фоновый поток уведомит основной поток о завершении, отправив -performSelectorOnMainThread:waitUntilDone:

1 голос
/ 01 сентября 2010

Не могли бы вы использовать блокировку для этого?Другими словами, что-то вроде этого (псевдокод)

  1. создать объект для блокировки, видимый для обоих потоков
  2. диспетчеризация потока A;поток A немедленно берет блокировку и удерживает ее в течение всего времени
  3. обработка чего-либо в главном потоке
  4. основной поток пытается захватить блокировку (это будет блокироваться до тех пор, пока поток A не снимет ее)
  5. после получения блокировки главный поток освобождает ее и продолжает
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...