ps:最近看了一下信号量,网上查找的资料整体感觉有点乱,所以自己总结了一下. 信号量主要就是GCD控制最大线程并发数量.create信号量设定数量,如果初始为 '1' 的时, 可以当成锁使用.
当性能要求较高时候,可以使用 pthread_mutex (互斥锁)或者 dispath_semaphore
1.信号量的三个方法
dispatch_semaphore_create => 创建信号量(设定数量)
dispatch_semaphore_signal => 发送一个信号(+1)
dispatch_semaphore_wait => 等待信号(-1)
2.三个方法的具体描述:
- 1.dispatch_semaphore_create的声明为:
dispatch_semaphore_t dispatch_semaphore_create(long value);
传入的参数为long,输出一个dispatch_semaphore_t类型且值为value的信号量。值得注意的是,这里的传入的参数value必须大于或等于0,否则dispatch_semaphore_create会返回NULL。
- 2.dispatch_semaphore_signal的声明为:
long dispatch_semaphore_signal(dispatch_semaphore_t dsema)
// 这个函数会使传入的信号量dsema的值加1;
dispatch_semaphore_signal的返回值为long类型,当返回值为0时表示当前并没有线程等待其处理的信号量,其处理的信号量的值加1即可。当返回值不为0时,表示其当前有(一个或多个)线程等待其处理的信号量,并且该函数唤醒了一个等待的线程(当线程有优先级时,唤醒优先级最高的线程;否则随机唤醒)。
dispatch_semaphore_wait的返回值也为long型。当其返回0时表示在timeout之前,该函数所处的线程被成功唤醒。当其返回不为0时,表示timeout发生。
- 3.dispatch_semaphore_wait的声明为:
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
// 这个函数会使传入的信号量dsema的值减1。
这个函数的作用是这样的,如果dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,并且将信号量的值减1;如果desema的值为0,那么这个函数就阻塞当前线程等待timeout(注意timeout的类型为dispatch_time_t,不能直接传入整形或float型数),如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量减1。如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
3.具体代码(主要看这个)
- (void)setThread{
/*当初始化为1的时候,可以作为锁使用, 如果初始化为0 ,你懂得*/
//定义一个信号量,初始化为10, 最大线程数为10,
dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
//同时执行100个任务,此时最多会开10个线程
for (int i = 0; i < 100; i++)
{
//信号量-1
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"任务%d执行%@",i+1,[NSThread currentThread]);
sleep(2);
//信号量+1
dispatch_semaphore_signal(semaphore);// 如果用一个button点击,则会发送信号,也能起作用
});
}
}
网友评论