GCD如何控制线程数量
多线程的使用,在开发中始终是一个绕不开的话题,关于多线程的实现方式,iOS目前也支持4种方式来实现,分别是:
多线程4种实现方式pthread,NSThread,GCD,NSOperation
至于四种实现方式的对比,在什么情况下使用哪个实现方式合适,这篇文章不谈(先种个草);这篇文章主要说明下GCD实现多线程的情况下,如何控制并发线程的数量;我们都知道在使用NSOperation+NSOperatonQueue的时候,想要控制线程的最大并发数量,非常的简单:
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; operationQueue.maxConcurrentOperationCount = 5;//控制线程最大并发数量
GCD在开发中使用场景非常多,而且GCD使用上来说相对简单些,那么如果在使用GCD的时候,如何控制线程数量呢?
答案是:信号量
dispatch_semaphore_t //Objective-C
DispatchSemaphore //Swift
关于信号量(semaphore),在开发过程中使用比较多的情况就是用来做锁;初始化一个1的信号量DispatchSemaphore.init(value: 1),在调用方法时先wait,如果信号量为1则执行方法体,如果不为1则等待;在具体方法完成后,执行signal;那么可以利用这样特性来控制GCD多线程中的最大并发数量;
首先定义一个全局的信号量(此处定义为5,则表示最大并发数为5)
在多线程的方法体中先调用wait,在方法执行完毕时候调用signal;
最初调用的时候semaphore为5,当有方法调用的时候,先调用wait对信号量-1,当同时有5个线程执行的时候(且全部未执行完毕的情况下),那么此时信号量为0,再有方法执行的时候,就会处于等待状态,待有方法体执行完毕调用signal是信号量增加,此时才能执行后续的方法;
具体代码如下:
let semaphore = DispatchSemaphore.init(value: 5)
func gcdrun(){
for index in 0..<10 {
DispatchQueue.global().async{
self.asyncaction(index)
}
}
}
func asyncaction(_ index: Int) {
semaphore.wait()
print("\(index) 开始")
sleep(UInt32(3+index))
print("\(index) 结束")
semaphore.signal()
}