暂停GCD查询问题 [英] Suspending GCD query problem
问题描述
我无法暂停gcd查询.这是一些演示问题的代码:
i have trouble suspending a gcd query. Here is some code that demonstrates the problem:
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,但是显然我的代码是错误的,并且查询q的两个实例都可以继续运行.
What I'm trying to do is suspend,release and reinitialise query q when function test is called the second time, but apparenty my code is wrong and both instances of query q continue to run.
非常感谢您的帮助.
推荐答案
在实际调用dispatch_suspend()之前已异步异步调度到队列中的任何块都将在挂起生效之前运行.在您的代码中,您正在异步触发一堆块,因此当您调用test(2)时,某些块可能仍在队列中,这些块将被执行.
Any blocks that have been dispatched to your queue asynchronously before you actually call dispatch_suspend() will get run before the suspend takes effect. In your code you are firing off a bunch of blocks asynchronously, so some are probably still in the queue when you call test(2), and those blocks will be executed.
如果您希望能够取消正在运行的作业,则需要按照自己的逻辑进行. GCD故意没有公开真正的取消API.您可以执行以下操作:
If you want to be able to cancel your running jobs, you'll need to do so in your own logic. GCD purposefully doesn't expose a true cancellation API. You could do something like this:
@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);}
});
}
通过这种方式,每个块都将保留对一个对象的引用,该对象知道它是否应该停止工作.
In this way, each block will keep a reference to an object that knows if it should stop doing work.
这篇关于暂停GCD查询问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!