Как правильно остановить фоновый процесс в Mac OS X? - PullRequest
1 голос
/ 27 апреля 2010

У меня есть приложение с 2 компонентами: настольное приложение, с которым взаимодействуют пользователи, и фоновый процесс, который можно включить из настольного приложения. После включения фонового процесса он будет запускаться как агент запуска пользователя независимо от приложения для настольного компьютера.

Однако мне интересно, что делать, когда пользователь отключает фоновый процесс. На данный момент я хочу остановить фоновый процесс, но я не уверен, что лучший подход. Я вижу 3 варианта:

  1. Используйте команду kill.
    • Прямо, но не надежно и просто кажется несколько "неправильным".
  2. Используйте NSMachPort для отправки запроса на выход из настольного приложения в фоновый процесс.
    • Это лучший подход, о котором я думал, но я столкнулся с проблемой реализации (я опубликую это в отдельном запросе), и я хотел бы быть уверен, что подход правильный прежде чем идти намного дальше.
  3. Что-то еще ???

Заранее благодарим вас за любую помощь / понимание, которое вы можете предложить.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2010

Я нашел более простой способ сделать это, используя объект NSConnection. Я создал очень простой объект ExitListener с таким заголовком:

@interface ExitListener : NSObject {
    BOOL _exitRequested;
    NSConnection *_connection;
}

@property (nonatomic, assign) BOOL exitRequested;

- (void)requestExit;

@end

и эта реализация:

@implementation ExitListener

@synthesize exitRequested = _exitRequested;

// On init we set ourselves up to listen for an exit
- (id)init {
    if ((self = [super init]) != nil) {
        _connection = [[NSConnection alloc] init];

        [_connection setRootObject:self];
        [_connection registerName:@"com.blahblah.exitport"];
    }
    return self;
}

- (void)dealloc {
    [_connection release];

    [super dealloc];
}

- (void)requestExit {
    [self setExitRequested:YES];
}

@end

Чтобы настроить прослушиватель, фоновый процесс просто выделяет и запускает экземпляр ExitListener. Затем настольное приложение запрашивает выход из фонового процесса, выполнив этот вызов:

- (void)stopBackgroundProcess {
    // Get a connection to the background process and ask it to exit
    NSConnection *connection = [NSConnection connectionWithRegisteredName:@"com.blahblah.exitport" host:nil];
    NSProxy *proxy = [connection rootProxy];
    if ([proxy respondsToSelector:@selector(requestExit)]) {
        [proxy performSelector:@selector(requestExit)];
    }
}

Использование NSMachPorts напрямую, казалось, привело к гораздо большим проблемам при регистрации и получении ссылок. Я обнаружил, что NSConnection - это самый простой способ создать базовый канал связи для ситуации, которую мне нужно было решить.

0 голосов
/ 27 апреля 2010

Демон может обрабатывать события выхода из apple или прослушивать CFMessagePort.

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

Если у вас есть очистка, которая может занять некоторое время, используйте что-то, кроме сигналов. Если вы просто вызываете выход, то с сигналами все в порядке.

Если у вас уже есть CFRunLoop, используйте CFMessagePort. Если вы уже обрабатываете события Apple, обработайте команду quit.

CFMessagePort - это оболочка для CFMachPort, которая предоставляет имя и некоторые другие удобства. Вы также можете использовать оболочки NS для любого из них.

...