将任务调度到队列中以便在另一个线程中运行任务

时间:2016-08-08 12:30:43

标签: ios objective-c multithreading grand-central-dispatch

人们在问what is the way to run task in an thread。许多人(从链接)接受的答案之一是使用GCD。

所以,我尝试通过这种方式打印出线程id,看看在放入GCD队列后该任务是否真的在另一个线程中执行了:

// a function in MyService class    
- (void) doTask {
        NSLog(@"start do task on thread = %@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_queue_create("com.company.myqueue", DISPATCH_QUEUE_SERIAL);
        dispatch_sync(queue, ^{
            NSLog(@"execute task on thread = %@", [NSThread currentThread]);
        });
    }

我跑:

// this is not main thread [myService doTask]

控制台输出是:

start do task on thread = <NSThread: 0x15b4be00>{number = 6, name = (null)}
execute task on thread = <NSThread: 0x15b4be00>{number = 6, name = (null)}

看起来任务没有在另一个线程中执行,它与调用者线程在同一个线程上。我误解了什么吗?为什么GCD不在单独的线程中执行任务,但很多人接受该链接中的答案?

3 个答案:

答案 0 :(得分:1)

GCD何时可以优化。同步运行块永远不需要切换线程,唯一的例外是调度到主队列,因为它必须在主线程上运行。

答案 1 :(得分:0)

尝试使用您在问题中提到的Accepted answer获取的以下代码。

   dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //

     NSLog(@"start do task on thread = %@", [NSThread currentThread]);


    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing

         NSLog(@"execute task on thread = %@", [NSThread currentThread]);
    });
});

它将打印两个不同的线程。在您放入问题的测试用例中,Thread是相同的,并且是synchronous方法。所以,它是打印相同的线程。这里解释一切都是非常广泛的概念。你应该参考Apple Documentation for GCD

文档说明了dispatch_sync

  

将一个块提交到调度队列以进行同步执行。与dispatch_async不同,此函数在块完成之前不会返回。调用此函数并以当前队列为目标会导致死锁。

     

与dispatch_async不同,不对目标执行保留   队列。因为对此函数的调用是同步的,所以它会借用&#34;   来电者的参考。而且,没有执行Block_copy   块。

     

<强>&GT;作为优化,此函数调用当前的块   尽可能的线程。

答案 2 :(得分:0)

检查

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dispatch_get_global_queue.3.html

它说

  

队列未绑定到任何特定的执行线程,并且提交给独立队列的块可能会同时执行。

因此,执行任务的线程选择由dispatch lib使用的线程牵引算法决定。但它保证队列执行是通过给定的队列配置(串行或并发和其他)来完成的