1

これが私のコードの簡略版です:

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

これはかなり基本的な fork() 呼び出しです。問題は、最上部の 2 行 (コメントでマークされている) が無視されることです...フォークされた子が終了するまで実行されないようです。なんで?

編集:それを修正するにはどうすればよいですか?

4

3 に答える 3

9

Cocoa アプリケーションを呼び出したくありませ 。そうするとき、約無数の落とし穴があります。そのほとんどは、マッハ ポートやその他のシステム バインディング インフラストラクチャなどのさまざまなリソースが境界を越えて存続する方法に関連しています。スレッドもあらゆる種類の地獄を引き起こします。fork()fork()

NSTask代わりに使用してください。内部的には効果的に行われfork()ますexec()が、正しく行われるように細心の注意を払って行われます。

于 2009-11-30T02:14:52.387 に答える
3

おそらく、GUI が状態を変更する前に、コードがメイン イベント ループに戻る必要があるためでしょうか? または、コードがカーネル レベルの wait() を実行している間、GUI を実行するスレッドがブロックされるため、わずかな違いがありますか?

于 2009-11-30T00:59:28.293 に答える
1

bbum はこれを正確に理解しました。最終的に使用したコードは次のとおりです。

- (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    
}
于 2009-11-30T03:22:52.297 に答える