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() 调用。问题是,最顶部的两行(标有注释)被忽略了......它们似乎直到分叉子退出后才执行。为什么?

编辑:我能做些什么来解决它?

4

3 回答 3

9

你真的真的 真的不想调用fork()Cocoa 应用程序。这样做时会有无数种不同的陷阱,主要与诸如 mach 端口和其他系统绑定基础设施等各种资源如何跨越fork()边界生存有关。线程也会导致各种地狱。

改为使用NSTask。虽然它有效地fork()/在exec()内部,但它会非常小心地确保它正确完成。

于 2009-11-30T02:14:52.387 回答
3

也许是因为您的代码必须在 GUI 更改状态之前返回到主事件循环?或者,由于运行 GUI 的线程在您的代码执行内核级 wait() 时被阻塞,所以略有不同?

于 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 回答