今天当我使用dispatch_async测试一些代码时,我发现了一个有趣的事情,当我运行这样的代码时:
static int temp = 1;
dispatch_queue_t defaultBackgroundQueue = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0);
dispatch_async(defaultBackgroundQueue, ^{
NSLog(@"blk 0 :%d", temp);
});
dispatch_async(defaultBackgroundQueue, ^{
NSLog(@"blk 1 :%d", temp++);
});
dispatch_async(defaultBackgroundQueue, ^{
NSLog(@"blk 2 :%d", temp);
});
猜猜日志是什么?这很有趣,像这样:
2016-02-29 21:39:40.700 GCDDemo[46594:3826498] blk 2 :2
2016-02-29 21:39:40.700 GCDDemo[46594:3826496] blk 1 :1
2016-02-29 21:39:40.696 GCDDemo[46594:3826495] blk 0 :1
在
temp
执行之前,我已尝试多次,即使第三个块首先完成,2
的值为++
。不应该是1
?
使用clang
将代码转换为C ++后,没有什么特别的关键代码:
static void __main_block_func_1(struct __main_block_impl_1 *__cself) {
int *temp = __cself->temp; // bound by copy
NSLog((NSString *)&__NSConstantStringImpl__var_folders_s6_v33rqm893pddvmp9w2hyfhtc0000gn_T_main_d902a1_mi_1, (*temp)++);
}
static int temp = 1;
dispatch_queue_t defaultBackgroundQueue = dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0);
dispatch_async(defaultBackgroundQueue, ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, &temp)));
dispatch_async(defaultBackgroundQueue, ((void (*)())&__main_block_impl_1((void *)__main_block_func_1, &__main_block_desc_1_DATA, &temp)));
dispatch_async(defaultBackgroundQueue, ((void (*)())&__main_block_impl_2((void *)__main_block_func_2, &__main_block_desc_2_DATA, &temp)));
你可以自己尝试一下,我在我的Mac book pro,OS X 10.11上进行了测试, 有人知道这个吗? 谢谢,
答案 0 :(得分:1)
这里会发生以下情况:
异步线程的完成顺序与您在print / log语句中看到的顺序不同,这意味着console.log(get_socketId("irc.freenode.com", 6667));
语句在任何其他线程之后执行设法对(共享)基础值NSLog
进行计算(这可能是因为temp
语句需要(相当多)在完成其他任何简单计算之前完成的时间。线程完成)。
鲍里斯也有一个有效的观点,显然,线程确实同时执行,我相信你已经意识到这一点,但首先并不总是那么明显。
答案 1 :(得分:0)
defaultBackgroundQueue
是并发的,因此您不应该按执行顺序进行中继。很可能,temp++
已经执行,但来自另一个区块的NSLog
不是。如果您想要不同的行为,请使用串行调度队列。
答案 2 :(得分:0)
将printf
更改为sleep
后,添加dispatch_async(defaultBackgroundQueue, ^{
sleep(1);
printf("blk 0:%d\n", temp);
});
dispatch_async(defaultBackgroundQueue, ^{
sleep(1);
printf("blk 1:%d\n", temp++);
});
dispatch_async(defaultBackgroundQueue, ^{
sleep(1);
printf("blk 2:%d\n", temp);
});
dispatch_async(defaultBackgroundQueue, ^{
sleep(1);
printf("blk 3:%d\n", temp);
});
:
blk 1:1
blk 0:2
blk 2:2
blk 3:2
结果发生了变化:
NSLog
正如@the_critic所说,echo $elem["Reference"];
echo $elem["Key"];
并不代表实际结果。
谢谢,