2010-12-09 44 views
2

我正在做異步套接字編程,並且我的代碼在大多數情況下工作,但有時卻不行。要點是:我創建一個套接字對,創建讀取和寫入流,然後當我想寫一些東西時,我將它安排在單獨線程的運行循環中。像這樣:CFWriteStreamScheduleWithRunLoop有時有效,有時不會?

CFStreamClientContext context = {0, sc, NULL, NULL, NULL}; 
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) { 
CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 
} 

...其中myWriteStreamCallback是正確格式的靜態函數...

插座/流被打開了,像這樣:

CFReadStreamRef readStream = NULL; 
CFWriteStreamRef writeStream = NULL; 

@try { 
    // create a pair of streams to the host and open them 

    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream); 
    if (readStream == NULL)  @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease]; 
    if (writeStream == NULL) @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease]; 
    if (!CFReadStreamOpen(readStream)) @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease]; 
    if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease]; 
    ... 

現在的問題:這個代碼(如果它能幫助任何人,還有更多的代碼)大部分都是正確的,因爲它大部分都是有效的。但是,有時候,在程序一開始,我可以嘗試以這種方式發送一些數據,並且套接字的回調將正確放置在運行循環中,但是它永遠不會被調用。在程序後面,相同的代碼將與另一個套接字一起運行,並且回調將被調用(套接字轉到相同的地址)。

我知道這是模糊的,但在我發佈所有代碼之前,是否有人對可能導致此問題的事情有任何粗略的想法?回調有時候沒有在runloops上被調用,也就是說。

哦,是的,我應該補充一點,這顯然是某種競爭條件 - 我可以不可靠地通過在正確的地方添加日誌記錄來消除問題。然後,它有時會起作用,有時候不會,而且具有完全相同的代碼。好玩。

的問題是,在其他線程使用的CFHostRef在一個線程中完成主機的分辨率:

回答

1

我從「奎因的愛斯基摩人」在蘋果論壇上獲得的溶液。這不好。

CFHost在同一個線程(上面的scomm.host對象)中完成的創建修復了問題。

相關問題