iOS 信号量机制《ios信号量, ios信号量使用》
信号量值又变为0,线程B有资源,其余线程必须等到,达到线程B的排他访问。 这就是信号量来控制线程互斥的原理。在GCD中有三个函数是semaphore的操作,分别是:第一个函数有一个长整形的参数,我们可以理解为信号的总量。
文章目录:
一、iOS 信号量机制
在 iOS 系统及大部分现代操作系统中,多个线程可以并发执行,CPU在线程之间来回切换,共享某些资源,提高了资源的利用率。 但是我们该如何处理各个线程之间的相互制约关系? 比如只有一台打印机,两个线程都需要打印文件,如果直接让他们简单的并发访问打印机,那么很可能什么都打印不出来或者打印的文件是混乱的。显然,我们需要增加一种机制来控制线程间的相互制约关系。
简单来说就是我们需要一种机制来控制线程执行的先后顺序。
而信号量就可以提供这样的一种机制,让一个临界区(临界区指的是线程中访问共用资源的程序片段)同一时间只有一个线程在访问它,也就是说信号量是用来协调线程对共享资源的访问的。
信号量可以理解为是一个资源计数器,对信号量有两个操作来达到互斥,分别是P和V操作。 一般情况是这样进行临界访问或互斥访问的: 设信号量值为1, 当一个线程A运行时,使用资源,进行P操作,即对信号量值减1,也就是资源数少了1个。这时信号量值为0。系统中规定当信号量值为0是,必须等待,直到信号量值不为零才能继续操作。 这时如果线程B想要运行,那么也必须进行P操作,但是此时信号量为0,所以无法减1,即不能P操作,也就阻塞。这样就达到了线程A的排他访问。 当线程A运行结束后,释放资源,进行V操作。资源数重新加1,这时信号量的值变为1,这时线程B发现资源数不为0,信号量能进行P操作了,立即执行P操作。信号量值又变为0,线程B有资源,其余线程必须等到,达到线程B的排他访问。 这就是信号量来控制线程互斥的原理。
在GCD中有三个函数是semaphore的操作,分别是:
第一个函数有一个长整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1,根据这样的原理,我们便可以快速的创建一个并发控制来同步任务和有限资源访问控制。
信号量是用在多线程并发的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。
1.信号量与锁的差别
2.浅谈GCD中的信号量
3.用信号量解决进程的同步与互斥探讨
二、iOS-GCD信号量实现最大并发
1.实现最大并发数,在iOS里,最容易使用的是NSOperationQueue,如下
NSOperationQueue中,已经考虑到了最大并发数的问题,并提供了maxConcurrentOperationCount属性设置最大并发数(该属性需要在任务添加到队列中之前进行设置)。maxConcurrentOperationCount默认值是-1;如果值设为0,那么不会执行任何任务;如果值设为1,那么该队列是串行的;如果大于1,那么是并行的。
2.用GCD信号量实现(默认你对信号量已有一定了解),如下:
解释:
我们可以看到,第1-4一共4条任务得以执行,然后只有完成一条或多条任务后,另一条或多条才能得以执行,控制了任务执行的最大数量是4条。
我们信号量给的是3,从结果来看最大并发数是4,这只是跟
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 这个方法在任务前还是后执行有关,如下:
三、IOS面试题(多线程) --- 锁
OC面试题目合集地址
基本的锁: 自旋锁 、 互斥锁 、 读写锁 ,其他的比如 条件锁 、 递归锁 、 信号量 都是上层的封装和实现。
锁的性能从高到底依次是:
OSSpinLock(自旋锁) >
dispatch_semaphone(信号量) >
pthread_mutex(互斥锁)>
NSLock(互斥锁)>
NSCondition(条件锁) >
pthread_mutex(recursive 互斥递归锁)>
NSRecursiveLock(递归锁)>
NSConditionLock(条件锁)>
synchronized(互斥锁)
会发生 死锁
使用NSLock对临界区进行加锁, 进入方法2, 方法2里面对同一把锁又进行了lock方法, 这种情况会由于重入原因发生 死锁
用递归锁解决, 利用其重入特性: 一个线程可以加N次锁而不会引发死锁
dispatch_semaphore_t 的关键3个方法
所以看出信号量一般处理 加锁(互斥) , 异步返回 , 控制线程并发数 这些场景。
重点考察多线程并发安全这一情况, 下面例子都以总20张票, 卖10张, 模拟一下:
可看出数据其实是错乱的
那么我们肯定是要加互斥锁, 来保证线程安全, 如下
可看出数据正常, 方法没问题是可以的。
这里再提供另外一个解法, 信号量 处理。 信号量 优势看下 问题2 锁的性能 , 其中有 dispatch_semaphone(信号量) > NSLock(互斥锁) 。 并且因为这道题数据量比较小, 如果复杂同步操作, 还是用 信号量 好一些, 那么我们用 信号量 保证下线程安全
到此,以上就是小编对于ios信号量的问题就介绍到这了,希望介绍关于ios信号量的3点解答对大家有用。