【问题标题】:Objective-C : Synchronized blocks and GCDObjective-C:同步块和 GCD
【发布时间】:2012-10-17 23:24:31
【问题描述】:

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

依次,我正在做的是:

  1. prepareData(调用后台线程)
  2. _doLongComputation(在后台线程中,调用_transferToGPU
  3. _transferToGPU(主线程)

由于我在同一对象 glData 上使用 synchronized 块,因此不应由多个线程同时访问临界区,但不幸的是,情况并非如此,我不能不知道为什么。

有什么想法吗?

代码的重要部分如下:

@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)];
}

【问题讨论】:

    标签: objective-c opengl grand-central-dispatch synchronized


    【解决方案1】:

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

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

    【讨论】:

    • 噢,该死的,我确信这很明显!当然最坏的情况发生了,我的对象被释放了,所以互斥锁没用了。谢谢你抓住它;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多