GCD - objective C

2018-06-07  本文已影响0人  __小赤佬__

GCD是一种比写底层thread code更简单的管理thread的方式。

有三种dispatch queue,它们都是thread safe的。queue上执行的是你指定的task,而queue上的task在哪个thread上运行,由queue自己决定(OS帮我们决定而非自己写)。

1、Serial。一般自己创建的private queue都是serial的,这有利于保护shared resources。多个serial dispatch queue可能同时执行,所谓serial是对于一个queue来说的。

// create a new serial queue
dispatch_queue_t queue;
queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_queue_t serialQueue = dispatch_queue_create("queue.my.serial", DISPATCH_QUEUE_SERIAL);

2、Global。这是一个concurrent的queue。可以通过DISPATCH_QUEUE_CONCURRENT这个type来创建一个concurrent queue,也可以用predefined global concurrent queues。

dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_queue_t concurrentQueue = dispatch_queue_create("queue.my.concurrent", DISPATCH_QUEUE_CONCURRENT);

3、Main queue。Main queue是serial的,只在main thread上运行。

sync VS async

async是说把工作安排到另一个queue上去。我们可以用它在非main queue上执行费时的工作,工作完成后再回到main queue去执行UI工作。sync是说暂停本线程的运行,直到短的任务执行完成后在继续运行,经常是setting or getting,可以prevent race condition。dispatch sync to the current queue will cause deadlock.

dispatch sync的方式就是说,要把dispatch的工作做完了,才继续执行code。dispatch async的方式,在calling thread上是non-blocking的。

dispatch_queue_t myCustomQueue;
  myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
  
dispatch_async(myCustomQueue, ^{
    printf("Do some work here.\n");
  });
  
printf("The first block may or may not have run.\n");
  
dispatch_sync(myCustomQueue, ^{
printf("Do some more work here.\n");
  });

printf("Both blocks have completed.\n");

结果是:

The first block may or may not have run.
Do some work here.
Do some more work here.
Both blocks have completed.

对于一个循环执行,可以用dispatch_apply进行concurrent的优化。这个函数是blocking的,会在所有循环执行完以后才return。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
int count = 4;
// i=0 in the first iteration, i=3 in the last iteration
dispatch_apply(count, queue, ^(size_t i) {
   printf("%u\n",i);
});

除了把一个task放到queue上以外,也可以制造一个group,可以用到的情景:group上所有task做完后,集中处理。比如:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
 
// Add a task to the group
dispatch_group_async(group, queue, ^{
   // Some asynchronous work
});
 
// Do some other work while the tasks execute.
 
// When you cannot make any more forward progress,
// wait on the group to block the current thread.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
 
// Release the group when it is no longer needed.
dispatch_release(group);

Reference

上一篇下一篇

猜你喜欢

热点阅读