2014-02-25 63 views
0

我正在Objective-C中編寫OSX應用程序。這是一個多線程應用程序。一個特定的線程執行一項任務(捕獲屏幕,在TCP套接字中寫入數據)並休眠200毫秒。它醒來後再次做同樣的工作。這一直持續到程序退出。還有另一個從TCP套接字讀取數據的線程。主線程僅顯示UI。CPU在特定時間點執行的當前代碼行

當我連續運行該程序一段時間後(2-3分鐘後),第一個線程的200ms睡眠時間急劇增加到5秒或10秒。我明白,當另一個線程正在運行時,第一個線程的休眠時間可能會延長。我添加了多個日誌打印到第二個線程。看來我的第二個線程不會阻塞CPU。

當睡眠時間持續很長一段時間時,我想知道除了我的第一個線程以外CPU執行哪一行代碼。 是否有可能知道CPU在特定時間點執行的當前代碼行?這將幫助我調試問題。

UPDATE:

爲了縮小範圍,我創建了一個簡單的程序,只是打印一個整數(自動遞增)每200ms。即使在這個簡單的程序中,問題也是可重複的。後一些300-400次迭代,方法調用時間增加至〜10秒(即,整數不是每200ms印刷,它在打印後約〜每次10秒)

#import "AppDelegate.h" 

@implementation AppDelegate 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    Screen* screen = [[Screen alloc] init]; 
    [NSThread detachNewThreadSelector:@selector(firstMethod) toTarget:screen withObject:nil]; 
} 

@end 

------------------------------------ 
#import <Foundation/Foundation.h> 

@interface Screen : NSObject 

-(void) firstMethod; 
-(void) secondMethod; 

@end 

---------------------------- 
#import "Screen.h" 

@implementation Screen 
int i=0; 
dispatch_queue_t another_queue; 

-(Screen*) init { 
    self = [super init]; 
    if (self) { 
     another_queue = dispatch_queue_create("com.test.timer", NULL); 
    } 
    return self; 
} 


-(void) firstMethod { 
    i++; 
    NSLog(@"i value : %d",i); 
    [self secondMethod]; 
} 

-(void) secondMethod { 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 200 * NSEC_PER_MSEC); 
    dispatch_after(popTime, another_queue, ^(void){ 
     [self firstMethod]; 
    }); 
} 

@end 
+0

對於睡眠,我用[NSThread sleepForTimeInterval:] 我也嘗試過dispatch_after(),結果相同。 –

+0

您可以使用'trace(1)'從您的應用程序獲取這種信息,甚至更容易,您可以使用它。也就是說,你應該使用一個合適的計時器,而不是一個正在睡覺的線程來做到這一點。 –

+0

@JasonCoco, 1.我認爲trace(1)必須插入我的代碼中。我將在哪裏添加這行代碼?當線程休眠時,我不知道正在執行的行(而是阻塞CPU)。 2。我試過Instruments,當線程休眠時,CPU變爲0%,我無法理解它的含義。這是否意味着我的線程正在等待某些資源?爲了避免睡眠,我甚至試過dispatch_after()。我也得到了同樣的結果(再次執行作業之前的延長時間)。 –

回答

0

如你所描述你的應用程序, 'CPU執行的當前代碼行'在大多數情況下將是'無',即。 CPU使用率確實是0%。如果GUI線程實際上不處理鼠標/ KB輸入,並且其他線程正在等待網絡數據或休眠,則什麼都沒有發生,並且沒有需要執行的代碼,因此CPU不是必需的。

Sleep()沒有什麼內在錯誤。調用它的線程將被阻塞直到間隔期滿,這取決於內核中的共享定時器隊列。沒有其他的線程/定時器/不需要,並且調用者的調用/返回上下文被保留,(不像使用明確的定時器)。休眠線程已準備就緒(不一定在運行,如其他人在註釋中所述),在經過的時間間隔後加上一些ms定時器抖動。通常,等待某事的線程(睡眠定時器,I/O或線程間同步器)在準備就緒時被賦予暫時的優先級提升,並且可以很快被合理快速地設置爲運行,除非您的框是重載運行更高優先級的線程,(如果CPU在睡眠期間使用下降到0,看起來不是這樣)。

「第一個線程的200ms睡眠時間急劇增加到5秒或10秒」的問題很可能不是睡眠()調用本身的一些神器。更有可能的是,通過的時間間隔實際上已被一些錯誤損壞,或者它不是產生額外延遲的Sleep()調用。也許你的網絡發送呼叫阻塞了很長一段時間,因爲服務器或鏈路速度慢,網絡緩衝區已滿?

+0

親愛的Martin James,我編輯了我原來的帖子並添加了一些更多的觀察。你能檢查一下嗎? –