Dlaczego nie mogę używać szkieletów kakao w różnych rozwidlonych procesach?
Grałem zNSSound
klasa do odtwarzania dźwięku w procesie w tle, tak aby nie blokować danych wprowadzanych przez użytkownika. Zdecydowałem się zadzwonićfork()
ale to sprawia mi problemy. W momencie przydzielenia dźwięku rozwidla się proces. Zabawne jest to, że jeśli skonstruuję przykład, który tylko wywołujefork()
, wtedy proces potomny może zadzwonićNSSound
bez problemów awarie pojawiają się tylko wtedy, gdy próbuję użyć innych API kakaoprzed fork()
połączenie. Zobacz ten przykład za pomocącrashme?()
skomentowano połączenia:
#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;
}
Kiedy uruchamiam to z linii poleceń, działa, ale jeśli odkomentuję jedno z tych wywołańcrashme?()
funkcje odtwarzanie w rozwidlonym procesie nigdy się nie uruchamia. Czy to dlatego, że żaden z API ramowych Cocoa nie jestasynchroniczny sygnał bezpieczny? Czy jest jakiś sposób na to, aby połączenia były asynchronicznie bezpieczne, zawijając je jakoś?