0

我有一个 OpenGL 应用程序,它需要在显示数据之前在后台执行一些计算。

按顺序,我正在做的是:

  1. prepareData(调用后台线程)
  2. _doLongComputation(在后台线程中,调用_transferToGPU
  3. _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)];
}
4

1 回答 1

2

我认为您应该改为在 self 上同步。

对变量进行同步在概念上会使用该变量指向的地址创建一个隐式互斥锁。如果变量指向不同的对象,它将是不同的互斥体,即使它在您的代码中仍然是同一个变量。这意味着在@synchronized(glData)块中设置 glData 会破坏同步尝试的目的。

于 2012-10-17T23:32:54.773 回答