如何在线程等待接收数据包时取消NSThread?

时间:2011-11-15 23:07:30

标签: objective-c nsthread

我有一个作为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 个答案:

答案 0 :(得分:2)

简而言之,你没有。您需要向套接字发送一个信号,表明它已关闭/死亡/例外或其他什么。

您必须仔细阅读unix级别的文档;我认为你应该能够关闭()套接字,但我不知道线程依赖。

另一种解决方案是使用具有超时的API;等待N秒,检查isCancelled,再等N秒等等......

远远更好的解决方案是根本不使用套接字API 。使用dispatch_source和/或CFStreams和/或其他一些更高级别的抽象。显然,如果要求可移植性,你就不能这样做(但是ObjC的交错与那段代码表明可移植性不是一个考虑因素。)

答案 1 :(得分:1)

您可以使用超时循环选择调用。如果select返回0,则它超时,因此您有机会检查取消标志,并退出线程或再次执行选择。如果有东西要接收,那么用recevfrom处理它并退出循环。