Как отменить NSThread, когда поток ожидает получения пакета? - PullRequest
0 голосов
/ 16 ноября 2011

У меня есть демон многоадресного приема, который работает как NSThread.Пока он ожидает получения, я хотел бы иметь возможность отменить его, не ожидая другого пакета, который может не прийти.Поскольку он просто ждет, я не могу выполнить другой код для проверки isCancelled.Как я могу это сделать?

Вот код, который получает .. Он сидит и ждет в первой строке, пока не поступит пакет.

/* block waiting to receive a packet */
            if ((recv_len = recvfrom(sock, recv_str, MAX_LEN, 0,
                                     (struct sockaddr*)&from_addr, &from_len)) < 0) {
                [delegate multicastDaemonDidFinish:self withError:@"recvfrom() failed"];

                exit(1);
            }
            receivedString = [NSString stringWithFormat:@"%s", recv_str];
            [delegate multicastDaemonDidReceiveData:self receivedString:receivedString];

В родительском, который такжеделегат, этот поток вызывается:

    [daemonThread initWithTarget:multicastDaemon selector:@selector(doWorkWithDelegate:) object:self];
    [daemonThread start];

Я могу выдать [daemonThread cancel], но daemonThread никогда не будет проверять isCancelled, пока он ждет.Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 16 ноября 2011

Короче, нет. Вам необходимо отправить сигнал в сокет, указывающий, что он закрыт / мертв / исключен или что-то в этом роде.

Вам придется внимательно прочитать документы по уровню Unix; Я думаю, вы должны иметь возможность закрыть () сокет, но я не знаю зависимости потоков.

Другое решение заключается в использовании API с тайм-аутом; подождите N секунд, проверьте isCancelled, подождите еще N секунд и т. д ...

Лучшее, гораздо лучшее решение - вообще не использовать API сокетов . Используйте dispatch_source и / или CFStreams и / или некоторую другую абстракцию более высокого уровня. Очевидно, что вы не сможете этого сделать, если будете использовать переносимость (но чередование ObjC с этим кодом указывает на то, что переносимость не учитывается).

1 голос
/ 16 ноября 2011

Вы можете зациклить на выбранном вызове с таймаутом.Если функция выбора возвращает 0, то по истечении этого времени у вас есть возможность проверить флаг отмены и либо выйти из потока, либо выполнить выбор снова.Если есть что получить, обработайте его с помощью recevfrom и выйдите из цикла.

...