在 dispatch_release(无 ARC 情况)之后的块中调用 dispatch_semaphore_signal 是否有任何问题?
Is there any issue to call dispatch_semaphore_signal in the block after dispatch_release(no ARC case)?
以下代码在超时时是否有问题(无 ARC 情况)?
在dispatch_release(信号量)之后调用dispatch_semaphore_signal怎么样?我知道一旦所有对它的引用都被释放(引用计数变为零),一个调度对象就会被异步释放,所以在下面的代码中信号量的引用不是0?
信号量需要加__block吗?
dispatch_time_t timeout = DISPATCH_TIME_FOREVER;
if (waitTime > 0)
{
timeout = dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC);
}
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_barrier_async(_dispatchQueue, ^{
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, timeout);
dispatch_release(semaphore);
非常感谢!
基于评论。
我想你需要这样的东西。 done
变量需要同步/原子,并且代码中有两个地方需要在某个公共锁上同步。事实上,由于您只访问这些片段中的 done
,因此不需要同步。
done = NO
dispatch_barrier ...
stuff
sync {
if(!done)
signal
done = YES;
}
wait with timeout
cancel block
sync {
if( ! done )
signal
done = YES
}
// You can even test the logic as below
if DEBUG
{
assert done == YES
}
release
我不确定取消块在非 ARC 环境中会产生什么影响,但我认为它会很好。
这将平衡信号和等待,并使释放起作用,同时防止您发出已释放信号量的信号。
这是Objective-C
中的大纲实现
__block BOOL done = NO;
NSObject * lock = NSObject.new;
dispatch_semaphore_t s = dispatch_semaphore_create ( 0 );
dispatch_queue_t queue = dispatch_queue_create( "bak",
dispatch_queue_attr_make_with_qos_class( DISPATCH_QUEUE_CONCURRENT,
QOS_CLASS_DEFAULT,
DISPATCH_QUEUE_PRIORITY_DEFAULT ) );
dispatch_block_t block = dispatch_block_create ( DISPATCH_BLOCK_BARRIER, ^ {
// Change this time to determine which one fires first
[NSThread sleepForTimeInterval:1];
@synchronized ( lock ) {
if ( ! done )
{
done = YES;
dispatch_semaphore_signal ( s );
NSLog ( @"Inside fired" );
}
}
} );
// Start the block
dispatch_async ( queue, block );
// ... or change time here to determine which one fires first
dispatch_semaphore_wait ( s, dispatch_time ( DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC ) );
@synchronized ( lock ) {
if ( ! done )
{
done = YES;
dispatch_semaphore_signal ( s );
NSLog ( @"Outside fired" );
}
}
// Done, release stuff *only* if not ARC
dispatch_release ( s );
dispatch_release ( queue );
dispatch_release ( block );
lock.release;
以下代码在超时时是否有问题(无 ARC 情况)?
在dispatch_release(信号量)之后调用dispatch_semaphore_signal怎么样?我知道一旦所有对它的引用都被释放(引用计数变为零),一个调度对象就会被异步释放,所以在下面的代码中信号量的引用不是0?
信号量需要加__block吗?
dispatch_time_t timeout = DISPATCH_TIME_FOREVER; if (waitTime > 0) { timeout = dispatch_time(DISPATCH_TIME_NOW, waitTime * NSEC_PER_SEC); } dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_barrier_async(_dispatchQueue, ^{ dispatch_semaphore_signal(semaphore); }); dispatch_semaphore_wait(semaphore, timeout); dispatch_release(semaphore);
非常感谢!
基于评论。
我想你需要这样的东西。 done
变量需要同步/原子,并且代码中有两个地方需要在某个公共锁上同步。事实上,由于您只访问这些片段中的 done
,因此不需要同步。
done = NO
dispatch_barrier ...
stuff
sync {
if(!done)
signal
done = YES;
}
wait with timeout
cancel block
sync {
if( ! done )
signal
done = YES
}
// You can even test the logic as below
if DEBUG
{
assert done == YES
}
release
我不确定取消块在非 ARC 环境中会产生什么影响,但我认为它会很好。
这将平衡信号和等待,并使释放起作用,同时防止您发出已释放信号量的信号。
这是Objective-C
中的大纲实现 __block BOOL done = NO;
NSObject * lock = NSObject.new;
dispatch_semaphore_t s = dispatch_semaphore_create ( 0 );
dispatch_queue_t queue = dispatch_queue_create( "bak",
dispatch_queue_attr_make_with_qos_class( DISPATCH_QUEUE_CONCURRENT,
QOS_CLASS_DEFAULT,
DISPATCH_QUEUE_PRIORITY_DEFAULT ) );
dispatch_block_t block = dispatch_block_create ( DISPATCH_BLOCK_BARRIER, ^ {
// Change this time to determine which one fires first
[NSThread sleepForTimeInterval:1];
@synchronized ( lock ) {
if ( ! done )
{
done = YES;
dispatch_semaphore_signal ( s );
NSLog ( @"Inside fired" );
}
}
} );
// Start the block
dispatch_async ( queue, block );
// ... or change time here to determine which one fires first
dispatch_semaphore_wait ( s, dispatch_time ( DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC ) );
@synchronized ( lock ) {
if ( ! done )
{
done = YES;
dispatch_semaphore_signal ( s );
NSLog ( @"Outside fired" );
}
}
// Done, release stuff *only* if not ARC
dispatch_release ( s );
dispatch_release ( queue );
dispatch_release ( block );
lock.release;