我有一个作为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。我怎么能这样做?
答案 0 :(得分:2)
简而言之,你没有。您需要向套接字发送一个信号,表明它已关闭/死亡/例外或其他什么。
您必须仔细阅读unix级别的文档;我认为你应该能够关闭()套接字,但我不知道线程依赖。
另一种解决方案是使用具有超时的API;等待N秒,检查isCancelled,再等N秒等等......
远远更好的解决方案是根本不使用套接字API 。使用dispatch_source和/或CFStreams和/或其他一些更高级别的抽象。显然,如果要求可移植性,你就不能这样做(但是ObjC的交错与那段代码表明可移植性不是一个考虑因素。)
答案 1 :(得分:1)
您可以使用超时循环选择调用。如果select返回0,则它超时,因此您有机会检查取消标志,并退出线程或再次执行选择。如果有东西要接收,那么用recevfrom处理它并退出循环。