我有一個有趣的問題與LLVM編譯器的優化級別有關。我使用的是:LLVM編譯器 - 這是一個優化錯誤嗎?
- 的Xcode 8.2.1
- LLVM 8.0
最好是用一個例子代碼來解釋它。我把這個問題歸結爲一個簡單的Objective-C類。請看下面的代碼第一:
@interface Foo() {
BOOL is_loading;
}
@end
@implementation Foo
- (void)test {
printf("started loading \n");
// set loading flag to YES
is_loading = YES;
// schedule a timer to fire in 2 seconds, to simulate the end of loading
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(timerFired)
userInfo:nil
repeats:NO];
// wait asynchronously until loading flag is set to NO
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (is_loading) {
// loop until timer event modifies is_loading flag
}
printf("finished loading \n");
});
}
- (void)timerFired {
printf("timer fired \n");
// set loading flag to NO
is_loading = NO;
}
@end
如果實例Foo
類並調用load
方法,它將模擬加載進度和異步觀察is_loading
標誌來確定是否加載完畢。
而在此之後,控制檯輸出將是這樣的:
started loading
timer fired
finished loading
但如果你打開編譯器的優化,你會看到這樣的輸出,而不是:
started loading
timer fired
顯然while循環永不結束,執行無法到達下一個printf()消息。
我是否錯過了這種情況發生的明顯原因,或者它可能是優化器錯誤?
謝謝,這工作..是時候把我的知識關於'volatile' :) – scener
我想補充說,簡單地添加'volatile'不會使代碼線程安全,所以它仍然可能會失敗。 –
這個答案被接受是不幸的。在這種情況下,在volatile中繁忙循環可能會起作用,但它會產生一些令人討厭的副作用,例如最大化CPU利用率。 –