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

私は同様の質問を見つけました、しかし私の場合、私はARCを使用しており、nowhere dispatch_release(sem); を明示的に書いていません。

4

3 に答える 3

2

semメソッドで作成した は、そのinitializeメソッドにローカルに適用されます。他のメソッドからアクセスできる必要があります。sem割り当てようとしているという名前の 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」に設定します。実行可能ファイルをビルドします。

次に、次の場所で実行します。

  • Intel Core i5: 'exc_i386_invop subcode=0x0' で (コンパイラが avx2 の使用を決定した場所で) クラッシュします。
  • Intel Core i7: 動作します。
于 2014-01-01T22:49:31.187 に答える