GCD - objective C
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);