我们都知道在GCD中有两个很重要的概念:线程和队列。在学习的时候对这两个概念都有了一定的了解,在此做一个学习记录(仅仅是个人理解)。
1.队列与线程
队列不是线程,队列是用来组织需要执行的任务,将任务加到队列中,任务会按照加入到队列中的顺序(先进先出)依次执行。线程就是依次取出队列中的任务来执行,(个人理解为:就像是在食堂排队打饭,把每一个学生看成为一个任务,按照顺序排队打饭,把打饭的窗口看成是线程,食堂根据排队情况安排开设几个窗口(线程))。
应用程序进程启动的时候主线程被系统创建,应用程序是需要不断的和用户进行交互,即主线程是需要一直存在。<NSThread: 0x600001292900>{number = 1, name = main}
,主线程只是系统创建的一个命名为main的线程,与其他线程应该是平等的,只不过在创建主线程的时候,主线程中加入了runloop使得主线程一直存在,不会退出。
1.主线程只能执行主队列中的任务?
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_set_specific(mainQueue, "key", &"key", NULL);
dispatch_sync(globalQueue, ^{
BOOL result1 = [NSThread isMainThread];
BOOL result2 = dispatch_get_specific("key") != NULL;
NSLog(@"1111is mainThread: %d --- is mainQueue: %d", result1, result2);
});
得到结果:当前在主线程但是不是主队列,由此可以看出主线程执行了其他队列的任务。
[10146:688118] 1111is mainThread: 1 --- is mainQueue: 0
2.主队列只能在主线程中执行?
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_set_specific(mainQueue, "key", &"key", NULL);
dispatch_async(globalQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"is mainThread==%d",[NSThread isMainThread]);
BOOL result2 = dispatch_get_specific("key") != NULL;
NSLog(@"is mainQueue==%d",result2);
});
});
dispatch_main();
执行结果如下:主队列并没有在主线程中
[10968:715046] is mainThread==0
[10968:715046] is mainQueue==1
但如果把 dispatch_main();
去掉,得到的结果就正常了
[10968:715046] is mainThread==1
[10968:715046] is mainQueue==1
dispatch_main();
* This function "parks" the main thread and waits for blocks to be submitted
* to the main queue. This function never returns.
此函数“驻停”主线程,并等待将代码块提交到主队列,并且无法返回。
此时是不是可以理解为:主队列任务通常是在主线程执行,当执行了dispatchMain()后,由于dispatchMain() 无法停止这个进程,只能选择强制退出,并且dispatchMain() 没有返回值,使得进程永远存在,所以系统选择让其他线程来执行主线程的任务。
大神分析:
多线程-奇怪的GCD
网友评论