多线程信号量,可以在多线程下控制多线程的并发数目。主要涉及三个方法:
1、创建信号量,可以设置信号量的资源数;
dispatch_semaphore_t dispatch_semaphore_create(long value);
2、通知信号,信号量的值加1;
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
3、等待信号,可以设置超时参数,信号量的值减1;
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
同时方法3等待信号也决定了该方法后面语句是否执行,什么时候执行的关键设置;如果dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,并且将信号量的值减1;如果desema的值为0,那么这个函数就阻塞当前线程等待timeout(注意timeout的类型为dispatch_time_t,不能直接传入整形或float型数),如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量减1。如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
这里举个例子,多个数据上传阿里云成功后,上传服务器进行数据单条数据存储;
__block BOOL isFailed = NO;
dispatch_semaphore_t sem = dispatch_semaphore_create(0); //当前信号量为0
[[UploadRecordCenter new]uploadImage:idNum withFileName:fileName success:^{
dispatch_semaphore_signal(sem);//信号量+1
} failure:^(NSString * _Nonnull errorMsg) {
dispatch_semaphore_signal(sem);//信号量+1
isFailed = YES;
}];
[[UploadRecordCenter new]uploadMP3:idNum withFileName:fileName success:^{
dispatch_semaphore_signal(sem);//信号量+1
} failure:^(NSString * _Nonnull errorMsg) {
dispatch_semaphore_signal(sem);//信号量+1
isFailed = YES;
}];
[[UploadRecordCenter new]uploadBRD:idNum withFileName:fileName success:^{
dispatch_semaphore_signal(sem);//信号量+1
} failure:^(NSString * _Nonnull errorMsg) {
dispatch_semaphore_signal(sem);//信号量+1
isFailed = YES;
}];;
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);//信号量-1,此时为-1,需要上面完成一个请求,信号量变为0,进行下面的操作;
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);//信号量-1,
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);//信号量-1
//上面3次请求都完成后进行下面的请求操作;
if (isFailed) {
NSLog(@"上传失败");
return ;
}
[[UploadRecordCenter new]uploadToServer:idNum success:^{
NSLog(@"上传成功");
} failure:^(NSString * _Nonnull errorMsg) {
NSLog(@"上传失败");
}];
由于create方法的参数必须>=0,所以上面需要完成多少个请求,就需要写几个wait方法;