Podría alguien, por favor, explique por qué tengo un error EXC_BAD_INSTRUCTION (código=EXC_I386_INVOP, subcódigo=0x0) en dispatch_semaphore_wait en el siguiente código:

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

He encontrado pregunta similar ¿Por qué hace este código causa «EXC_BAD_INSTRUCTION»?, pero en mi caso yo estoy usando el ARCO y no escribo de forma explícita en ninguna parte dispatch_release(sem);

  • Cómo es una «cola» que se define? Claramente el uno en -inicializar no es el mismo.
  • el mismo, se me olvidó añadir el código que se asigna a las variables locales a las variables de instancia
  • Así que… uh… ¿todavía tiene el problema ahora que usted ha fijado, el código? Porque si que fija el código, entonces usted debe aceptar la respuesta, no editar la pregunta para hacerla inútil.
  • Yo no cambio el código, he editado sólo algunos errores tipográficos y inexactitud sólo en el texto que he publicado aquí. Ahora el código es el código que tengo en el programa. Así que la respuesta es NO, no se soluciona el problema.
  • Está usted seguro de que el método de instancia initialize ha sido invocada en todo antes de enviar method1 y método method2? Compruebe si el semáforo y cola de ivar no es nil antes de su uso, por ejemplo,assert(self.sem). También, el código hace que no munch sentido. El uso del semáforo tampoco es correcto, ya que no impiden el acceso de la matriz, incluso si está vacío, así que usted obtenga una excepción.
  • lo siento, de nuevo era inexacta y se olvidó de agregar código de inicialización de una matriz de aquí. Esperemos que ahora lo tengo todo en el código.initialize siempre se invoca antes de enviar method1 y method2, por lo que el semáforo y la cola son no nulas cuando estoy con ellos. También matriz es inicializado y tiene un elemento en ella al principio. En un hilo siempre me llaman, en fin method1, method2 method1, method2… así que no hay ninguna posibilidad de que en el hilo de una matriz vacía. Pero cuando otro hilo que desee acceder method1 debe esperar, hasta que el primer hilo de la señal en method2.
  • posibles duplicados de EXC_BAD_INSTRUCTION (código=EXC_I386_INVOP, subcódigo=0 x 0)

InformationsquelleAutor zyxel | 2013-08-01

3 Comentarios

  1. 2

    La sem creó en su initialize método es de ámbito local a ese método. Debe ser accesible a los otros métodos. Si usted tiene un iVar nombre sem que usted está tratando de asignar, está sombreado por declaración de una variable local en initialize. (Lo mismo con queue, por cierto.)

    También, que parecen tener un error tipográfico aquí, en que llame a dispatch_semaphore_wait(sen, DISPATCH_TIME_FOREVER); (es decir, se n vs se m)

  2. 1

    Se permite el acceso simultáneo a la matriz self.myarray sin la debida protección. Modificar la matriz con -addObject: y -removeObjectAtIndex: en la serie de la cola de self.queue pero leer usando -objectAtIndex: sin ningún tipo de protección. Esto significa que usted puede ser la lectura de la misma en el mismo tiempo en que la escritura, que no es seguro. También es necesario poner el -objectAtIndex: llamada en la serie de la cola.

    También, está utilizando funciones de la barrera con una serie de cola, que no tiene ningún sentido.

    -(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);
      });
    }
  3. 0

    Este tipo de accidente puede ocurrir cuando se ejecuta un (vector)de extensión que no es compatible con la CPU.

    Por ejemplo, en xcode 5 en el marco del «proyecto-ajustes /construir-ajustes /Generación de Código, establezca la
    «Activar el Vector extensions» a «AVX2». Construir el ejecutable.

    Ahora ejecutar en un:

    • Intel Core i5: se va a bloquear (donde el compilador decidió utilizar avx2) con ‘exc_i386_invop subcódigo=0 x 0’.
    • Intel Core i7: va a trabajar.
    • Esto no funciona para mí. Cuando intento llamar tableColumn?.identifier en tableView:viewForTableColumn:row: en mi Mesa delegado me sale este error
    • Intenta deshabilitar el vector extensions ( avx2, sse, etc ) y ver si en algún momento se va a trabajar.
    • Lo siento, eso fue hace un rato. Yo almacenados por NSTextFields en una matriz y acceder a aquellas. Gracias por la ayuda, aunque 🙂

Dejar respuesta

Please enter your comment!
Please enter your name here