Pregunta

Aquí hay una versión simplificada de mi código:

- (IBAction)convert:(id)sender
{
    /* these two lines are ignored */
    [textbox setStringValue:@"converting"];
    [convertButton setEnabled:NO];

        pid_t pid;
        if((pid=fork())==-1)
        {
            [log setStringValue:@"couldn't fork a new process."];
            converting = 0;
        [convertButton setEnabled:YES];
            return;
        }else if (pid==0)
        {
            //this is the child
            sleep(2);
            exit(0);
        }else{
            int status;
            waitpid(pid,&status,0);
        }
    }
}

Es una llamada fork () bastante básica. El problema es que las dos líneas en la parte superior (marcadas con un comentario) se ignoran ... no parecen ejecutarse hasta después que el niño bifurcado sale. ¿Por qué?

Editar : ¿Y qué puedo hacer para solucionarlo?

¿Fue útil?

Solución

Realmente realmente realmente no desea llamar a fork () en una aplicación de Cocoa. Al hacerlo, hay aproximadamente un billón de problemas diferentes, principalmente relacionados con la forma en que varios recursos como puertos de mach y otras infraestructuras de enlace del sistema sobreviven a través del límite fork () . Los hilos también causan todo tipo de infierno.

Utilice NSTask en su lugar. Si bien efectivamente hace fork () / exec () internamente, lo hace con considerable cuidado para asegurarse de que se haga correctamente.

Otros consejos

¿Quizás porque su código debe volver al bucle de eventos principal antes de que la GUI pueda cambiar de estado? ¿O una ligera variación, porque el subproceso que ejecuta la GUI está bloqueado mientras su código está haciendo una espera a nivel de kernel ()?

bbum hizo esto exactamente bien. Aquí está el código que terminé usando:

- (IBAction)convert:(id)sender
{
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/usr/local/bin/lame"];

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects: file,outputFile, nil];
    [task setArguments: arguments];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskFinished:) name:NSTaskDidTerminateNotification object:task];

    [task launch];  
}
- (void) taskFinished:(NSNotification *)note {
    // code here executes after process finishes    
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top