分叉过程似乎吃掉了某些代码行 - Objective-C
-
08-07-2019 - |
题
以下是我的代码的简化版本:
- (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()调用。问题是,顶部的两行(用注释标记)被忽略......它们似乎不会执行,直到分叉的子项退出后。为什么呢?
修改:我该怎么办才能修复它?
解决方案
你真的真的 真的不想在Cocoa应用程序中调用 fork()
。这样做有大量不同的问题,主要与各种资源(如mach端口和其他系统绑定基础设施)在 fork()
边界中的存在有关。线程也会导致各种各样的地狱。
请改用 NSTask
。虽然它在内部有效地执行 fork()
/ exec()
,但它确实非常谨慎,以确保正确完成。
其他提示
也许是因为你的代码必须在GUI可以改变状态之前返回主事件循环?或者,稍有不同,因为在代码执行内核级wait()时,运行GUI的线程被阻塞了?
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
}
不隶属于 StackOverflow