读取串行数据时CPU消耗和延迟都很高

时间:2012-10-25 00:07:43

标签: objective-c multithreading cocoa serial-port usb

我的软件中有两个功能会导致严重的延迟问题。该软件是用Objective-C编写的。我从USB设备接收串行数据,我的目标是封装它们,然后将它们发送到另一个处理数据的对象。

该程序的这一部分导致大的cpu和延迟问题,我根本不知道如何解决这个问题。设备只在状态发生变化时才发送数据,因此当发生很多变化时,一切都会变得迟钝。

- (void)getSerialData {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
    [self getSerialDataLoop];
    });
}

- (void)getSerialDataLoop {

readThreadRunning = YES;

char byte_buffer[2]; // buffer for holding incoming data
int numBytes=0; // number of bytes read during read
NSString *text;

// this will loop untilthe serial port closes
while(TRUE) {
    // read() blocks until some data is available or the port is closed
    numBytes = (int)read(serialFileDescriptor, byte_buffer, 1); // read up to the size of the buffer

    if(numBytes>0) {
        ///text = [NSString stringWithCString:byte_buffer encoding:NSSymbolStringEncoding];
        if(![text isEqualToString:@""]){
            text = [NSString stringWithUTF8String:byte_buffer];
            [self performSelectorOnMainThread:@selector(processNSStringData:) withObject:text waitUntilDone:YES];
        }
    } else {
        break; // Stop the thread if there is an error
    }

}
// make sure the serial port is closed
if (serialFileDescriptor != -1) {
    close(serialFileDescriptor);
    serialFileDescriptor = -1;
}

// mark that the thread has quit
readThreadRunning = FALSE;
}

你有什么想法或指示吗?

1 个答案:

答案 0 :(得分:1)

你基本上已经在这里彻底改造了NSStream。我首先建议您调查这个已经可用的解决方案,该解决方案与运行循环相关联。

通过调用getSerialData,您也可以轻易地压倒自己。系统中没有任何内容可以防止多次调用此例程,如果进行多次调用,您将进行并发操作。使用NSStream可以解决这个问题。但是,在任何情况下,如果已经运行了新的读取块,则不应继续创建新的读取块。

您还在阅读一个字节并进行处理。这可能是您最大的影响。为每个字节回调主线程可能非常昂贵。如果没有别的,你要为每个字节创建一个新的NSString对象。

请注意,您的代码非常危险,可能会崩溃。你从不初始化byte_buffer,你只读了一个字节。当你调用stringWithUTF8String:时,你假设第二个字节是\ 0,这取决于堆栈的当前状态。