我有一个OpenGL应用,需要在显示数据之前在后台执行一些计算。
顺便说一下,我正在做的是:
prepareData
(调用后台线程)_doLongComputation
(在后台主题中,调用_transferToGPU
)_transferToGPU
(主线索)由于我在同一个对象synchronized
上使用glData
块,因此不应同时访问多个线程的关键部分,但遗憾的是情况并非如此,我无法弄清楚原因。
有什么想法吗?
代码的重要部分如下:
@property (atomic, retain) NSData *glData;
...snip snip...
- (void) _doLongComputation {
@synchronized (glData) {
// Create a buffer (long operation, done in C++)
unsigned long size;
unsigned char* buffer = createBuffer(&size);
// Create NSData to hold it safely
self.glData = [NSData dataWithBytesNoCopy:buffer length:size freeWhenDone:YES];
}
// Don't wand to deal with locking the OpenGL context,
// so we do all the OpenGL-related stuff in the main queue
dispatch_async (dispatch_get_main_queue(), ^{
[self _transferToGPU];
});
}
- (void) _transferToGPU {
@synchronized (glData) {
...snip snip...
// Transfer buffer to GPU
glBufferData(GL_ARRAY_BUFFER,
glData.length,
glData.bytes,
GL_STATIC_DRAW);
// We're done, so set the buffer to nil
self.glData = nil;
}
}
- (void) prepareData {
[self performSelectorInBackground:@selector(_doLongComputation)];
}
答案 0 :(得分:2)
我认为你应该自我同步。
在变量上同步在概念上使用该变量指向的地址创建隐式互斥锁。如果变量指向不同的对象,它将是一个不同的互斥锁,即使它仍然是代码中的相同变量。这意味着在@synchronized(glData)
块中设置glData会破坏同步尝试的目的。