我正在Objective-C中编写OSX应用程序。它是一个多线程应用程序。一个特定的线程完成一项工作(捕获屏幕,在TCP套接字中写入数据)并休眠200毫秒。它醒来并再次做同样的工作。这将持续运行,直到程序退出。还有另一个线程从TCP套接字读取数据。主线程只显示UI。
当我连续运行该程序一段时间后,经过一段时间(约2-3分钟后),第一个线程的200ms睡眠会急剧增加到5秒或10秒。据我所知,当另一个线程正在运行时,第一个线程的休眠时间可能会延长。我在第二个帖子中添加了多个日志打印。似乎我的第二个线程没有阻止CPU。
当休眠时间持续很长一段时间时,我想知道CPU执行的代码行不是我的第一个线程。 是否可以知道CPU在特定时间点执行的当前代码行?这将帮助我调试问题。
更新:
为了缩小范围,我创建了一个简单的程序,它每200ms只打印一个整数(自动递增)。即使在这个简单的程序中,问题也是可重现的。经过300-400次迭代后,方法调用时间增加到~10秒(即,每200毫秒不打印整数。每次约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 :(得分:0)
正如您所描述的应用程序一样,“CPU执行的当前代码行”在大多数情况下将是“无”,即。 CPU使用率确实为0%。如果GUI线程实际上没有处理鼠标/ KB输入,而其他线程正在等待网络数据或休眠,则不会发生任何事情并且没有需要执行的代码,因此不需要CPU。
Sleep()没有任何内在错误。调用它的线程将被阻塞,直到间隔到期,这由内核中的共享定时器队列确定。没有其他线程/定时器/无论什么是必需的,并且保留了调用者的调用/返回上下文(与使用显式定时器不同)。在通过的间隔加上一些ms定时器抖动之后,休眠线程就会准备好(不一定是运行,如评论中的其他人所描述的)。通常情况下,等待某些东西的线程(睡眠定时器,I / O或线程间同步),无论如何都会在准备就绪时获得临时优先级提升,并且除非您的盒子是盒子,否则可以合理地快速设置运行更高优先级的线程超载(如果CPU在睡眠期间使用率降至0,则似乎不是这样)。
'第一个线程的200ms睡眠急剧增加到5秒或10秒'的常见问题不太可能是Sleep()调用本身的一些神器。更有可能的是,通过的间隔实际上已被某些错误破坏,或者不是Sleep()调用产生了额外的延迟。也许您的网络发送呼叫在较长时间内是阻塞的,因为服务器或链路很慢并且网络缓冲区已满?