Ответ 1
Из этой страницы, похоже, есть некоторые довольно сложные проблемы с потоками, специфичные для внедрения python. Есть ли причина, по которой вы не могли просто запускать эти скрипты в отдельном процессе? Например, следующий -runBunchOfScripts
метод будет запускать script десять раз (вызывая -runPythonScript
) в параллельной фоновой очереди, собирая результирующие выходы в массив строк и затем вызывая свой объект обратно в основной поток после завершения всех скриптов:
- (NSString*)runPythonScript
{
NSTask* task = [[[NSTask alloc] init] autorelease];
task.launchPath = @"/usr/bin/python";
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"MyScript" ofType:@"py"];
task.arguments = [NSArray arrayWithObjects: scriptPath, nil];
// NSLog breaks if we don't do this...
[task setStandardInput: [NSPipe pipe]];
NSPipe *stdOutPipe = nil;
stdOutPipe = [NSPipe pipe];
[task setStandardOutput:stdOutPipe];
NSPipe* stdErrPipe = nil;
stdErrPipe = [NSPipe pipe];
[task setStandardError: stdErrPipe];
[task launch];
NSData* data = [[stdOutPipe fileHandleForReading] readDataToEndOfFile];
[task waitUntilExit];
NSInteger exitCode = task.terminationStatus;
if (exitCode != 0)
{
NSLog(@"Error!");
return nil;
}
return [[[NSString alloc] initWithBytes: data.bytes length:data.length encoding: NSUTF8StringEncoding] autorelease];
}
- (void)runBunchOfScripts
{
dispatch_group_t group = dispatch_group_create();
NSMutableArray* results = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < 10; i++)
{
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString* result = [self runPythonScript];
@synchronized(results)
{
[results addObject: result];
}
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[self scriptsDidFinishWithResults: results];
dispatch_release(group);
[results release];
});
}
- (void)scriptsDidFinishWithResults: (NSArray*)results
{
NSLog(@"Do something with the results...");
}
Естественно, что подход использования отдельных процессов имеет ограничения, не в последнюю очередь являющиеся жестким ограничением количества процессов, которые вы можете запускать, но он кажется намного менее опасным, чем внедрение всего интерпретатора. Я бы сказал, что, если вам не нужно взаимодействовать между сценариями и хостинговой средой, это будет лучшим подходом.