关于GCD信号量dispatch_semaphore_signal
2016-10-11 18:57
405 查看
最近在做一些连接硬件拍照的工作,在iOS设备上控制相机拍照,遇到了一些问题,现记录如下:
下面的两段代码主要功能是:创建一个信号量Semaphore,然后创建一个定时器,每隔一段时间查询相机状态.当相机处理完毕之后,发出信号,继续执行以后的操作.整个过程都是在全局队列中处理的.
然而,在数据处理完毕,以下代码信号已经发出
并且定时器也已经销毁的前提下,dispatch_semaphore_wait竟然不执行!百思不得其解!
最后,还是得求助万能的stackoverflow
这个是类似问题
其中指出:
Most likely you are running out of threads. The dispatch_semaphore_signal(semaphore) , which should release the dispatch_semaphore_wait() needs to be executed in a new thread (see objectForKey:block: for details). If OS fails to dispatch that new thread, you stuck, as nobody will send you the dispatch_semaphore_signal.
How often and when it happens depends on computer/device speed, how fast you scroll the table etc. That’s why you can’t reproduce this issue on your computer.
也就是说,dispatch_semaphore_signal需要在新的线程中执行,否则如果操作系统指派当前线程失败,你就永远收不到它发出的信号.
受此启发,在定时器外层另开一个线程
问题解决!!!
下面的两段代码主要功能是:创建一个信号量Semaphore,然后创建一个定时器,每隔一段时间查询相机状态.当相机处理完毕之后,发出信号,继续执行以后的操作.整个过程都是在全局队列中处理的.
- (NSString*)run:(NSString*)command { // Create and keep HTTP session NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session= [NSURLSession sessionWithConfiguration:config]; _commandId = command; // Semaphore for synchronization (cannot be entered until signal is called) _semaphore = dispatch_semaphore_create(0); // Create and start timer NSTimer *timer = [NSTimer timerWithTimeInterval:0.5f target:self selector:@selector(getState:) userInfo:nil repeats:YES]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSRunLoopCommonModes]; [runLoop run]; // Wait until signal is called dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); return _state; } /** * Delegate called during each set period of time * @param timer Timer */ - (void)getState:(NSTimer*)timer { // Create JSON data NSDictionary *body = @{@"id": _commandId}; // Set the request-body. [_request setHTTPBody:[NSJSONSerialization dataWithJSONObject:body options:0 error:nil]]; // Send the url-request. NSURLSessionDataTask* task = [_session dataTaskWithRequest:_request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (![_state isEqualToString:@"inProgress"]) { dispatch_semaphore_signal(_semaphore); // Stop timer [timer invalidate]; } }]; [task resume]; }
然而,在数据处理完毕,以下代码信号已经发出
dispatch_semaphore_signal(_semaphore);
并且定时器也已经销毁的前提下,dispatch_semaphore_wait竟然不执行!百思不得其解!
最后,还是得求助万能的stackoverflow
这个是类似问题
其中指出:
Most likely you are running out of threads. The dispatch_semaphore_signal(semaphore) , which should release the dispatch_semaphore_wait() needs to be executed in a new thread (see objectForKey:block: for details). If OS fails to dispatch that new thread, you stuck, as nobody will send you the dispatch_semaphore_signal.
How often and when it happens depends on computer/device speed, how fast you scroll the table etc. That’s why you can’t reproduce this issue on your computer.
也就是说,dispatch_semaphore_signal需要在新的线程中执行,否则如果操作系统指派当前线程失败,你就永远收不到它发出的信号.
受此启发,在定时器外层另开一个线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSTimer *timer = [NSTimer timerWithTimeInterval:0.5f target:self selector:@selector(getState:) userInfo:nil repeats:YES]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSRunLoopCommonModes]; [runLoop run]; });
问题解决!!!
相关文章推荐
- dispatch_semaphore_signal和dispatch_semaphore_wait信号量
- GCD 信号量控制并发 (dispatch_semaphore)
- GCD之关于dispatch_semaphore的使用
- iOS GCD之dispatch_semaphore(信号量)
- GCD-信号量(dispatch_semaphore_t)
- GCD 第四篇 dispatch_semaphore(信号量)
- GCD(二) ---- dispatch_semaphore 信号量
- GCD 信号量控制并发 (dispatch_semaphore)
- GCD 信号量控制并发 (dispatch_semaphore)
- iOS多线程开发—— GCD dispatch_semaphore 信号量
- GCD 信号量控制并发(dispatch_semaphore)以及dispatch_group_async
- iOS GCD中级篇 - dispatch_semaphore(信号量)的理解及使用
- GCD 信号量 dispatch_semaphore_t
- 完整详解GCD系列(四)dispatch_semaphore(信号量)
- 完整详解swift GCD系列(四)dispatch_semaphore(信号量)
- 利用GCD信号量(dispatch_semaphore)控制并发
- 完整详解GCD系列(四)dispatch_semaphore(信号量)
- iOS GCD中级篇 - dispatch_semaphore(信号量)的理解及使用
- iOS GCD - dispatch_semaphore(信号量)
- iOS GCD中级篇 - dispatch_semaphore(信号量)的理解及使用