2011-11-15 23 views
0

我有一个作为NSThread运行的多播接收守护进程。当它等待接收时,我希望能够取消它,而不用等待另一个可能不会来的包。由于它只是等待,我不能执行其他代码来检查isCancelled。我怎样才能做到这一点?如何在线程正在等待接收数据包时取消NSThread?

这里是正在接收的代码。它坐在那里,直到包是在第一行等待

/* 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取消],但daemonThread在他等待时不会检查isCancelled。我怎样才能做到这一点?

回答

1

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

+0

选择将解决我的问题。我还没有取消工作,但我确实已经选择了工作,并且很快就能取消工作。谢谢! – Adam

2

总之,你没有。你需要发送一个信号给套接字,表明它已经关闭/死/例外等等。

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

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

远远更好的解决方案是根本不使用套接字API,所有的套接字API都是。使用dispatch_source和/或CFStreams和/或其他更高级别的抽象。显然,如果考虑到可移植性,你不能这么做(但是,ObjC的交叉/代码表示可移植性不是考虑因素)。