ParseSourceCodeStudy icon indicating copy to clipboard operation
ParseSourceCodeStudy copied to clipboard

串行队列中,异步会新建线程,只开一条线程的说法不够严谨吧?

Open jianzhi2010 opened this issue 9 years ago • 4 comments

在GCD 扫盲篇中提到: 异步:1)因为必定会开启新的线程,线程的申请是由异步负责,起到开分支的作用; 2)串行队列 :会新建线程,只开一条线程 一条线程就够了;

但是,如果在主队列中执行异步操作的话,是不会开启新线程的。

jianzhi2010 avatar Nov 16 '15 04:11 jianzhi2010

查了下资料,说

主队列中的操作都是在主线程中执行的,不存在异步的概念

那意思就是说

    dispatch_async(dispatch_get_main_queue(), ^{
        // code
    });

这段代码是完全没作用的,其实还是在主队列同步执行?

AngryLi avatar Nov 16 '15 06:11 AngryLi

串⾏行队列同一时间只执行单一任务, GCD的API很大程度上基于block 1.主线程队列 主线程队列 内部执行任务是串行的同步操作 主线程队列不需要我们创建,通过dispatch_get_main_queue()方法获得 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(queue, ^{ [self taskThread1]; }); 或者 dispatch_async(dispatch_get_main_queue(), ^{ [self taskThread2]; });

LiRenee avatar Nov 16 '15 14:11 LiRenee

的确不太严谨,改天修改下,你看比较合适的说法应该是怎样的?

ChenYilong avatar Nov 26 '15 17:11 ChenYilong

Remarks: lv(Str) : Log Verbose ${Str} lm() : Log Method

- (void)viewDidLoad {
    lm();
    [super viewDidLoad];

    lv(@"block facade");

    dispatch_async(dispatch_get_main_queue(), ^{
        lv(@"block inside");
    });

    lv(@"block outside");

}

- (void)viewWillAppear:(BOOL)animated {
    lm();
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    lm();
    [super viewDidAppear:animated];
}

Logs:

🎈-[ViewController viewDidLoad] + 26📍 🎈-[ViewController viewDidLoad] + 29📍 block facade 🎈-[ViewController viewDidLoad] + 35📍 block outside 🎈-[ViewController viewWillAppear:] + 40📍 🎈-[ViewController viewDidAppear:] + 45📍 🎈__29-[ViewController viewDidLoad]_block_invoke + 32📍 block inside

We could learn that main queue dispatch comes from a system call by GCD at the CF method

__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);

The argument "msg" is a MachPort message. So..the main queue dispatch is related 2 kernel status transition (user space <--> kernel space) which is completed by mach_msg_trap(). It cannot be profiled in just one word as "performed synchronously in main thread". As a result, the CF method above will be called in a new run of the main thread runloop which is awaked by the MachPort message whose (livePort == dispatchPort) . And the dispatched block is involved in the MachPort message argument.

The whole of what I said could be referred from CoreFoundation/CFRunLoop.c

ljysdfz avatar Jan 31 '16 02:01 ljysdfz