2011-11-15 70 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的交叉/代碼表示可移植性不是考慮因素)。