2.GCD多线程整理

来源:互联网 发布:洲际巡航导弹知乎 编辑:程序博客网 时间:2024/05/21 13:43

说明:该文整理自《Object-C高级编程》

1.任务队列

Dispatch Queue:FIFO结构的任务队列,等待线程处理,分成串行和并行两种模式。串行为单线程(同时被处理的任务只能有一个),并行为多线程,可以有多个任务被同时处理。

用户职能操作队列,而不能操作线程。

貌似并没有提供限制最大线程数量接口API。

serial dispatch queue:用在多个线程想更新相同的数据资源,这种方式能确保数据的安全

concurrent dispatch queue:不发生数据竞争的时,可以使用并行的队列 

 

2.API列表

//默认为串行队列

1.创建队列

dispatch_queue_t queid = dispatch_queue_create(“cc.app”, NULL);

DISPATCH_QUEUE_CONCURRENT 并行


2.释放队列(需手动释放,ARC并不负责队列释放)

dispatch_release(quid);

3.持有队列

dispatch_retain(queid); 

4.异步提交任务

dispatch_async(queid,^{…});

特别说明:异步提交的时候会隐式的调用dispatch_retain,确保队列可靠,被其它对象给释放

流程:

dispatch_create();

dispatch_async();

dispatch_release(); //提交后立即释放,也能确保任务能够被处理


进程的主线程队列和系统全局队列

5.获取主线程队列

dispatch_get_main_queue

6.获取全局队列

全局队列为并行队列有四种优先级:

DISPATCH_QUEUE_PRIORITY_LOW

DISPATCH_QUEUE_PRIORITY_DEFAULT

DISPATCH_QUEUE_PRIORITY_HIGH

DISPATCH_QUEUE_PRIORITY_BACKGROUND 

dispatch_get_global_queue

7.修改队列优先级

dispatch_set_target_queue

默认优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT

可以修改queue的执行阶层

如果在多个serial queue中调用dispatch_set_target_queue,并且目标queue相同,那么这个时候原本本应并行执行的多个queue在目标中职能一次执行一个 ,由并行转串行,有没有先后顺序呢?


优先级设置方式ex:

dispatch_queue_t queid;

dispatch_queue_t global_que = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, NULL);

dispatch_set_target_queue(queid, global_que);

8.在指定多少时间后添加任务

dispatch_after

ex:3秒后追加到任务队列中

dispatch_time_t ntime = dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);

dispatch_after(time, dispatch_get_main_queue, ^{});

NSEC_PER_SEC 单位为秒

NSEC_PER_MSEC 单位为毫秒

 

dispatch_walltime 计算绝对时间,添加到指定队列


9.Dispatch group

等待一组任务完成后,通知,然后继续执行

dispatch_group_create 创建一个任务组

dispatch_group_async 向这个组提交任务

dispatch_group_notify 任务做完后通知

dispatch_group_wait 阻塞当前线程,进行阻塞

dispatch_release 释放

ex:

dispatch_queue_t queid = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, quid, ^{});

dispatch_group_async(group, quid, ^{});

dispatch_group_async(group, quid, ^{});

//任务做完后进行通知

dispatch_group_notify(group, dispatch_get_main_queue(), ^{});

dispatch_release(group);

//等待用法,返回为0表示任务都结束,否则未结束

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);


10.Dispatch Barrier

很强大的功能,有点类似读写锁,但由于读写锁(不会有饿死现象)

ex:

dispatch_async(queue, block0);

dispatch_async(queue, block1);

dispatch_async(queue, block2);

dispatch_async(queue, block3);

dispatch_barrier_async(queue, block_block);

dispatch_async(queue, block4);

dispatch_async(queue, block5);

dispatch_async(queue, block6);

状态分析:block0, block1, block2结束后,运行block_block

  然后并行运行block4, block5, block6

 

11.同步提交

dispatch_sync:同步提交任务,注意死锁

ex:如果以下代码在主线中运行则会死锁

dispatch_queue_t queid = dispatch_get_main_queue();

dispatch_sync(queid, ^{}); 

即:程在执行的时候会锁定自己的任务队列,当它自己向自己提交任务时,会进行再次加锁,这个时候就会造成死锁。

所以线程千万不要自己向自己提交任务,或者直接用异步方式也挺好


12.dispatch_apply按照指定的次数提交到任务队列,会等待任务结束


13.dispatch_suspend/dispatch_resume挂起或者唤醒队列,已经执行的任务不会停止


14.GCD方式的信号量

dispatch_semaphore_t semt = dispatch_semaphore_create(1);

dispatch_semaphore_wait(semt, DISPATCH_TIME_FORVER);  //返回值为0,获取了资源,否则超时

dispatch_semaphore_signal(semt);

dispatch_release(setmt);

15.dispatch_once 只执行一次初始化

static dispatch_once_t pred;

dispatch_once(&pred, ^{});

通过数据类型dispatch_once_t来进行保证

16.Dispatch IO

Page167,Page172,通过IO事件来进行驱动 

0 0
原创粉丝点击