ios developers

GCD简单分析

2022-09-07  本文已影响0人  ios小喽喽

GCD:Grand Central Dispatch,纯C语言,是Apple公司为多核的并行运算提出的解决方案

GCD会自动利用更多的CPU内核(比如双核、四核)

GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

dispatch_queue_t:调度队列

DISPATCH_QUEUE_SERIAL(NULL):串行队列标识

创建串行队列:dispatch_queue_t serial = dispatch_queue_create("car", DISPATCH_QUEUE_SERIAL);

DISPATCH_QUEUE_CONCURRENT:并行队列

创建并行队列:dispatch_queue_t conque = dispatch_queue_create("car", DISPATCH_QUEUE_CONCURRENT);

创建主队列:  dispatch_queue_t mainQueue = dispatch_get_main_queue();

系统并行队列: dispatch_queue_t globQueue = dispatch_get_global_queue(0, 0);

异步:dispatch_async 

特点:不用等待当前语句执行完毕,就可以执行下一条语句、会开启线程执行block的任务

同步:dispatch_sync

特点:必须等待当前语句执行完毕才会执行下一条语句、不会开启线程、在当前执行的block

图(1) 图(2) 图(3)

由上面的截图可以看出,异步线程在串行和并发队列中是先执行,然后才到主线程

图(4)

由上面的截图可以看出,异步线程在主队列中是先执行主线程,在到异步线程中执行

图(5) 图(6) 图(7)

由上面的截图可以看出,同步线程在串行和并发队列中是先执行,然后才到主线程

图(8)

由上面的截图可以看出,同步线程在主队列中是死锁。

把任务添加到队列中:

图(9)

函数与队列:

图(10)

主队列与全局队列:

主队列(dispatch_get_main_queue()):在主线程上调度任务的串行队列、不会开启线程。如果当前主线程正在执行任务,那么无论主队列中当前添加了什么任务,都不会被调度。

全局并发队列dispatch_get_global_queue(0, 0) :是一个并发队列,在多线程开发时,如果队列没有特殊需求,在执行异步任务时,可以直接使用全局队列。

死锁现象:主线程因为你同步函数的原因等着先执行任务,主队列等着主线程的任务执行完毕过后才执行自己的任务,主队列和主线程相互等待会造成死锁。

 栅栏函数(dispatch_barrier_async、dispatch_barrier_sync):控制任务执行顺序,前面的任务执行完成才会来到这里,dispatch_barrier_sync会堵塞线程,影响后面的程序执行,只能控制同一并发队列。

图(11) 图(12) 图(13)

信号量dispatch_semaphore_t:

图(14)

Dispatch_Source:

图(15) 图(16)

锁的归类:

自旋锁:线程反复检查锁变量是否可用。由于线程在这一过程保持执行,因此是一种忙等待,一旦获取自旋锁,线程就会保持该锁,直至释放自旋锁,自旋锁避免了进程上下文的调度开销,因此对于线程只会阻塞很短时间的场合是有效的。

互斥锁:(NSLock、pthread_mutex、@synchronized)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写机制,该目的通过将代码切成一个一个的灵界区而达成。

条件锁:(NSCondition、NSConditionLock)就是条件变量,当进程的某些资源要求不满足时进入休眠就锁住了,当资源被分配到了,条件锁打开,进程继续

递归锁:(NSRecursiveLock、pthread_mutex(recursive))就是同⼀个线程可以加锁N次⽽不会引发死锁。

信号量(semaphore):(dispatch_semaphore)是⼀种更⾼级的同步机制,互斥锁可以说是semaphore在仅取值0/1时的特例。信号量可以有更多的取值空间,⽤来实现更加复杂的同步,⽽不单单是线程间互斥。

读写锁:

图(17) 图(18)

锁的性能数据:

图(19)
上一篇下一篇

猜你喜欢

热点阅读