我正在与NSSound
班级一起玩,以在我自己的后台进程中播放声音,以免阻止用户输入。我决定打电话fork()
,但这给我带来了问题。在分配声音的那一刻,分叉的进程崩溃了。有趣的是,如果我构建一个只调用的示例fork()
,那么子进程可以NSSound
毫无问题地调用,只有当我在调用之前fork()
尝试使用其他可可 API 时才会出现崩溃。请参阅带有crashme?()
注释的调用的示例:
#import <AppKit/AppKit.h>
#import <math.h>
#define FILENAME \
"/System/Library/Components/CoreAudio.component/" \
"Contents/SharedSupport/SystemSounds/dock/drag to trash.aif"
void crashme1(void)
{
NSString *path = [[NSString alloc] initWithUTF8String:"false file"];
NSSound *sound = [[NSSound alloc]
initWithContentsOfFile:path byReference:YES];
}
void crashme2(void)
{
NSInteger tag = 0;
[[NSWorkspace sharedWorkspace]
performFileOperation:NSWorkspaceRecycleOperation
source:@"." destination:nil
files:[NSArray arrayWithObject:@"false file"] tag:&tag];
}
double playAif(void)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *path = [[NSString alloc] initWithUTF8String:FILENAME];
NSSound *sound = [[NSSound alloc]
initWithContentsOfFile:path byReference:YES];
[path release];
if (!sound) {
[pool release];
return -1;
}
const double ret = [sound duration];
[sound play];
[sound autorelease];
[pool release];
return ret;
}
int main(int argc, char *argv[])
{
//crashme1();
//crashme2();
int childpid = fork();
if (0 == childpid) {
printf("Starting playback\n");
double wait = playAif();
sleep(ceil(wait));
wait = playAif();
sleep(ceil(wait));
printf("Finished playback\n");
}
return 0;
}
当我从命令行运行它时,它可以工作,但是如果我取消注释对任一crashme?()
函数的调用之一,则分叉进程中的播放永远不会开始。是不是因为任何 Cocoa 框架 API 都不是异步信号安全的?有没有办法通过以某种方式包装它们来使调用异步信号安全?