2009-08-30 2 views
2

Кто-нибудь еще видел или слышал о каких-либо проблемах с NSTask в 10.6?Проблемы с NSTask в OS X 10.6 Snow Leopard

Этот код работал хорошо вчера и сегодня не работает.

NSTask *task = [converter task]; 
[task waitUntilExit]; 
NSLog(@"Task did complete"); 

Задача делает то, что он должен делать (я проверил выход, и это хорошо), но программа будет ждать неопределенное время метода waitUntilExit. У меня есть несколько модульных тестов, которые используют похожий код, все они прошли ранее, но по состоянию на вчерашний день они больше не работают.

+0

Что произойдет, если вы замените простой скрипт, который просто вытаскивает выход 0; для той, которую вы используете сейчас? –

+0

Я вижу аналогичную проблему, когда вышеприведенный код иногда заканчивается немедленно, а иногда занимает несколько секунд или больше. Действительно странно! – Locksleyu

ответ

0

Проверьте пс, сверху или Монитор активности. Убедитесь, что ваш процесс завершен.

+0

Он отображается в мониторе активности и прекращается. Файлы, которые конвертируются, преобразуются и не повреждаются. Похоже, что задача завершается, но почему-то не информирует кого-либо о том, что она завершена. – kubi

1

(1) Вы обрабатываете выход из задачи каким-либо образом? Если это так, буферизация вывода может блокироваться, если вы не читаете & обрабатываете данные по пути.

(2) Завершается ли ваша задача EOL на stdin перед завершением? Если это так, вы захотите захватить stdin и явно закрыть его.

Как сказал Питер, проверьте ps, чтобы проверить, все ли работает ваша задача. Если да, используйте sample, чтобы пробовать его, чтобы выяснить, что это такое.

1

Возможно, я заметил проблему с некоторым из моего кода на 10.6, который звучит подозрительно, как ваша проблема.

Мне нужно было получить информацию о сети (в основном относительно BGP и материала AS) полностью асинхронным образом. Идеальным решением для меня является отправка специальных запросов на запись DNS TXT на общедоступный DNS-сервер, но Cocoa/Core Foundation не предоставляет API для выполнения таких запросов DNS с нечетным шаром. Другой способ состоял в том, чтобы использовать shell% whois -h IP 'SPECIAL REQUEST' и просто разбирать соответствующую информацию с выхода. Это было то, что я мог бы встать и запустить в течение нескольких часов, а потом вернуться и поставить реальное решение. Очень хакерский, но ужасно много быстрее, чем 1) нахождение подходящей асинхронной библиотеки DNS и 2) переход на скорость по API и, возможно, создание для нее обертки.

Итак, я создал класс, который разворачивает фоновый поток, а затем NSTask, чтобы начать запрос whois. Фоновый поток находится в цикле NSRunLoop для обработки результатов, но проверяет каждые ~ 1/10 секунды, чтобы узнать, умер ли по какой-либо причине NSTask или [NSThread isCanceled] и т. Д. Он также регистрирует уведомления NSApplicationWillTerminateNotification, чтобы он мог делать надлежащая очистка, если приложение уходит.

Ну, с 10,6 ... Я больше не мог уходить «быстро». В 10.5 все стекло гладко, и приложение закрывается мгновенно, по крайней мере, перцептивно. В разделе 10.6 выключение приложения приведет к зависанию. Отладка показала, что все подвешивается, пытаясь убрать затяжку whois NSTask. Поскольку ни одна из информации, которую я получаю таким образом, не имеет решающего значения для функциональных возможностей приложений (это дополнительно, приятно знать какую-либо информацию), я просто отучился и остановился, пытаясь получить информацию в виде решения о блокировке.

Быстрый переход при отладке проблемы показал, что основное приложение блокировалось при попытке получить экземпляры NSLock. Интересно, что если я просто оставлю это в покое, приложение, в конечном счете, выйдет нормально - где-нибудь от 10-20 секунд до минут .. что-то изменилось между 10.5 и 10.6, что вызывает код, заключенный в квадрат в блоке [NSLock lock] ... [NSLock unlock], чтобы «занять много времени», , Мне еще предстоит отследить, где это происходит, хотя (еще не приоритет) ....но одна из таких вещей заканчивается фоном NSTask, если он все еще работает и «ждет его завершения», прежде чем он сможет безопасно избавиться от таких вещей, как его NSPipe.

DUP: Это может быть обманным ответом ... мой первый, похоже, исчез в одном из них?

+0

Это очень похоже на мою проблему. Я не касаюсь NSLock, новый процесс полностью контролируется через NSTask, поэтому моя проблема лежит где-то там. Отстой, что у вас нет (пока) есть решение, но я буду держать вас в курсе, если я что-нибудь придумаю. – kubi

2

Вам нужно добавить следующую магическую строку:

[task setStandardInput:[NSPipe pipe]]; 
0

Не уверен, если это поможет, но вы можете попробовать сделать ожидание в отдельном потоке:

[NSThread detachNewThreadSelector: @selector(foo) toTarget: self withObject: task]; 

... 

- (void) foo: (NSTask *) task { 
    [task launch]; 
    [task waitUntilExit]; 
    ... 

У меня была проблема, где Я не получил NSNotification, когда задача завершилась, и это исправило это. По-видимому, есть некоторые ошибки в реализации NSTask под 10.6 ...

Смежные вопросы