暂停GCD查询问题
我无法暂停gcd查询。 下面是一些代码,演示了这个问题:
static dispatch_queue_t q=nil; static void test(int a){ if(q){ dispatch_suspend(q); dispatch_release(q); q=nil; } q=dispatch_get_global_queue(0,0); dispatch_async(q,^ { while(1){NSLog(@"query %d",a);sleep(2);} }); } int main(int argc, const char* argv[]){ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; test(1); //blah blah blah test(2); while(1){} [pool release]; return 0; }
我试图做的是挂起,释放和重新初始化查询q时,第二次调用函数testing,但显然我的代码是错误的,并且查询q的两个实例继续运行。
非常感谢您的帮助,谢谢。
在实际调用dispatch_suspend()之前asynchronous调度到队列的任何块将在暂停生效之前运行。 在你的代码中,你正在asynchronous地触发一堆块,所以当你调用test(2)时,有些块可能还在队列中,并且这些块将被执行。
如果你想取消你正在运行的工作,你需要用你自己的逻辑去做。 GCD有目的地不公开一个真正的取消API。 你可以做这样的事情:
@interface Canceller { BOOL _shouldCancel; } - (void)setShouldCancel:(BOOL)shouldCancel; - (BOOL)shouldCancel; @end @implementation Canceller - (void)setShouldCancel:(BOOL)shouldCancel { _shouldCancel = shouldCancel; } - (BOOL)shouldCancel { return _shouldCancel; } @end static void test(int a){ static Canceller * canceller = nil; if(q){ [canceller setShouldCancel:YES]; [canceller release]; dispatch_suspend(q); dispatch_release(q); q=nil; } canceller = [[Canceller alloc] init]; q=dispatch_get_global_queue(0,0); dispatch_async(q,^ { while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);} }); }
通过这种方式,每个块将保持对知道是否应该停止工作的对象的引用。
来自Apple GCD参考 :
dispatch_suspend
通过暂停调度对象,您的应用程序可以暂时阻止与该对象关联的任何块的执行。 在通话结束后,发生中断 。 调用此函数会增加对象的暂停计数,并调用dispatch_resume来减less它的暂停计数。 当计数大于零时,对象保持暂停状态,因此您必须将每个dispatch_suspend调用与匹配的dispatch_resume调用进行平衡。
[大胆的我]
我认为这是因为当一个块被执行时,它会离开队列。 所以,看来你不能暂停已经执行的程序段。