1

请有人解释一下为什么我在以下代码中的 dispatch_semaphore_wait 中收到错误 EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0):

-(void) initialize {
  dispatch_queue_t queue = dispatch_queue_create("My queue", NULL);
  dispatch_semaphore_t sem = dispatch_semaphore_create(1);
  self.queue = queue;
  self.sem = sem;
  self.myarray = [[NSMutableArray alloc]init];
  [self.myarray addObject: [[MyObject alloc] init]];
}
-(MyObject *) method1 {
  //do something
  dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
  MyObject *obj = [self.myarray objectAtIndex:0];
  dispatch_barrier_sync(self.queue, ^{
    [self.myarray removeObjectAtIndex:0];
  });
  return obj;
}

-(void) method2:(MyObject *)object {
  //do something
  dispatch_barrier_async(self.queue, ^{
    [self.myarray addObject:object];
    dispatch_semaphore_signal(self.sem);
  });
}

我发现了类似的问题为什么这段代码会导致“EXC_BAD_INSTRUCTION”?,但在我的情况下,我使用的是 ARC,并且我没有明确写出 nowhere dispatch_release(sem);

4

3 回答 3

2

sem您在方法中创建的本地initialize范围为该方法。它需要可供其他方法访问。如果您sem尝试分配一个名为 iVar 的 iVar,则通过在initialize. (顺便说一句,与 相同queue。)

此外,您在这里似乎有一个错字,因为您调用了dispatch_semaphore_wait(sen, DISPATCH_TIME_FOREVER);(即 se n vs se m

于 2013-08-01T13:49:45.077 回答
1

self.myarray您允许在没有足够保护的情况下同时访问阵列。-addObject:您使用和-removeObjectAtIndex:在串行队列上修改阵列,但您在没有任何保护的情况下self.queue从它读取。-objectAtIndex:这意味着您可能在写入的同时正在读取它,这是不安全的。您还需要将-objectAtIndex:呼叫放在串行队列上。

此外,您正在使用带有串行队列的屏障函数,这没有任何意义。

-(MyObject *) method1 {
  //do something
  dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
  __block MyObject *obj;
  dispatch_sync(self.queue, ^{
    obj = [self.myarray objectAtIndex:0];
    [self.myarray removeObjectAtIndex:0];
  });
  return obj;
}

-(void) method2:(MyObject *)object {
  //do something
  dispatch_async(self.queue, ^{
    [self.myarray addObject:object];
    dispatch_semaphore_signal(self.sem);
  });
}
于 2014-01-01T23:01:11.657 回答
0

当您运行 CPU 不支持的(矢量)扩展时,会发生这种崩溃。

例如,在“project-settings / build-settings / Code Generation”下的 xcode 5 中,将“Enable Additional Vector extensions”设置为“AVX2”。构建您的可执行文件。

现在运行它:

  • 英特尔酷睿 i5:它将崩溃(无论编译器决定使用 avx2),并带有“exc_i386_invop subcode=0x0”。
  • 英特尔酷睿 i7:它会工作。
于 2014-01-01T22:49:31.187 回答