2014-02-25 57 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,我编辑了我原来的帖子并添加了一些更多的观察。你能检查一下吗? –