Question

Voici une version simplifiée de mon code:

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

Il s’agit d’un joli appel fork () de base. Le problème est que les deux lignes tout en haut (marquées d'un commentaire) sont ignorées ... elles ne semblent pas s'exécuter avant après la sortie de l'enfant créé. Pourquoi?

Modifier : Et que puis-je faire pour résoudre ce problème?

Était-ce utile?

La solution

Vous vraiment ne souhaitez pas appeler fork () dans une application Cocoa. Il existe environ un million de pièges différents, principalement liés à la survie de diverses ressources telles que les ports mach et autres infrastructures de liaison système au-delà de la limite fork () . Les fils causent aussi toutes sortes d’enfer.

Utilisez plutôt NSTask . Bien que fork () / exec () fonctionne effectivement en interne, il le fait avec beaucoup de soin pour s'assurer que tout est fait correctement.

Autres conseils

Peut-être parce que votre code doit retourner à la boucle d'événements principale avant que l'interface graphique puisse changer d'état? Ou bien, une légère variation, car le thread qui exécute l'interface graphique est bloqué pendant que votre code exécute une attente au niveau du noyau ()?

bbum a tout à fait raison. Voici le code que j'ai fini par utiliser:

- (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    
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top