在我的应用程序中,我在每个芯片的多个管道上的多个芯片上执行大量异步 I/O。
一些操作由多个操作组成。例如,要从其中一个芯片读取序列号,我必须执行两次写入和两次读取:写入命令检查序列号缓冲区大小,读取结果。写命令读取序列号值,读取结果。
这是该操作的简化代码:
- (BOOL)readSerialNumber:(NSMutableString*)serialNumber
{
if(nil == serialNumber)
return FALSE; // Nowhere to store.
if(![self sendCommand:GetSerialNumberSize])
return FALSE;
// Set up some matching event data (not shown), then check it....
BOOL matched= FALSE;
BOOL timeUp= FALSE;
[self setEventWasMatched:FALSE];
NSDate* timeUpDate= [[NSDate alloc] initWithTimeIntervalSinceNow:2.0];
while((!timeUp) && !matched)
{
matched= [self eventWasMatched]; // Match state is set from receive code in another thread.
timeUp= (NSOrderedDescending != [timeUpDate compare:[NSDate date]]);
}
[timeUpDate release];
NSUInteger serialNumberSize= matchedEvent.serialNumberSize;
if(0 == serialNumberSize)
return FALSE;
if(![self sendCommand:GetSerialNumber ofSize:serialNumberSize])
return FALSE;
// Set up some matching event data (not shown), then check it....
matched= FALSE;
timeUp= FALSE;
[self setEventWasMatched:FALSE];
timeUpDate= [[NSDate alloc] initWithTimeIntervalSinceNow:2.0];
while((!timeUp) && !matched)
{
matched= [self eventWasMatched]; // Match state is set from receive code in another thread.
timeUp= (NSOrderedDescending != [timeUpDate compare:[NSDate date]]);
}
[timeUpDate release];
[serialNumber.setString:matchedEvent.serialNumber];
return (0 != [serialNumber length]);
}
- (void)setEventWasMatched:(BOOL)matched
{
[lockMatch lock];
eventMatched= matched;
[lockMatch unlock];
}
- (void) eventWasMatched
{
BOOL wasMatched= FALSE;
[lockMatch lock];
wasMatched= eventMatched;
[lockMatch unlock];
return wasMatched;
}
此代码示例可能无法编译或工作,但它是我正在工作的代码的一个不错的表示。
我在这里有几件事有疑问:
我一直认为 BOOL 的 set/get 函数中的 NSLock 访问是昂贵的,就像在 setEventWasMatched 和 eventWasMatched 中一样。SO question 10094361 参考了一些分析,Apple Thread Programming Guide 指出“虽然锁是同步两个线程的有效方法,但获取锁是一项相对昂贵的操作,即使在无争议的情况下也是如此。” 我怎样才能以更有效的方式做到这一点?
我从 Allocations 工具中知道,大量内存用于在我的循环中创建 NSDate 对象以检查事件匹配。我不能对匹配进行开放式检查,因为我的匹配标准可能永远不会得到满足。有什么更好的方法呢?
任何输入将不胜感激。有人可能会说使用 NSOperation/NSOperationQueue 或 GCD,但相信我,这个示例是简单操作之一。还有一些涉及多个读/写对,一些写/多个读等。