IO蓝牙同步读取
现在我正在使用 IOBluetooth 开发一个程序,我需要同步读取,即我调用一个方法,它将给定数量的字节写入端口,然后读取给定数量并返回它们。我目前有一个由 NSThreads、NSLocks 和 NSConditions 组成的复杂系统,虽然它可以工作,但速度非常慢。另外,在某些调用之后,我需要确保没有额外的数据,所以我通常会刷新缓冲区,但是使用 IOBluetooth 的异步回调这是不可能的 - 关于如何确保无论如何,之后收到的所有数据的任何想法特定点是在该点之后收到的数据?
我真的没有处理过这种类型的同步和多线程,因为到目前为止我所做的所有工作都是使用同步调用,所以我很感激对此事的任何想法。
这是传入数据的回调(“incomingData”对象是 NSMutableData):
- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength {
[dataLock lock];
NSData *data = [NSData dataWithBytes:dataPointer length:dataLength];
[incomingData appendData:data];
if (dataWaitCondition && [incomingData length] >= bytesToWaitFor) {
[dataWaitCondition signal];
}
[dataLock unlock];
[delegate bluetoothDataReceived];
}
这是在返回数据对象之前等待直到接收到给定字节数的方法(这是从备用线程调用的)。
- (NSData *)waitForBytes:(int)numberOfBytes {
bytesToWaitFor = numberOfBytes;
[dataLock lock];
dataWaitCondition = [[NSCondition alloc] init];
[dataWaitCondition lock];
[dataLock unlock];
while ([incomingData length] < numberOfBytes) {
[dataWaitCondition wait];
}
[dataLock lock];
NSData *data = [incomingData copy];
[dataWaitCondition unlock];
dataWaitCondition = NULL;
[dataLock unlock];
return data;
}
Right now I'm working on a program using IOBluetooth and I need to have synchronous reads, i.e. I call a method, it writes a given number of bytes to the port, then reads a given number and returns them. I currently have a complex system of NSThreads, NSLocks, and NSConditions that, while it sort of works, is very slow. Also, after certain calls, I need to make sure there's no extra data, so I'd normally flush the buffer, but with IOBluetooth's asynchronous callback that's not possible - any thoughts on how to make sure that no matter what, all data received after a specific point is data that's received after that point?
I really haven't dealt at all with synchronization and multithreading of this type, since all the work I've done so far is using synchronous calls, so I'd appreciate any thoughts on the matter.
Here's the callback for incoming data (the "incomingData" object is NSMutableData):
- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength {
[dataLock lock];
NSData *data = [NSData dataWithBytes:dataPointer length:dataLength];
[incomingData appendData:data];
if (dataWaitCondition && [incomingData length] >= bytesToWaitFor) {
[dataWaitCondition signal];
}
[dataLock unlock];
[delegate bluetoothDataReceived];
}
And here's the method that waits until the given number of bytes has been received before returning the data object (this gets called from an alternate thread).
- (NSData *)waitForBytes:(int)numberOfBytes {
bytesToWaitFor = numberOfBytes;
[dataLock lock];
dataWaitCondition = [[NSCondition alloc] init];
[dataWaitCondition lock];
[dataLock unlock];
while ([incomingData length] < numberOfBytes) {
[dataWaitCondition wait];
}
[dataLock lock];
NSData *data = [incomingData copy];
[dataWaitCondition unlock];
dataWaitCondition = NULL;
[dataLock unlock];
return data;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以同步方式进行任何类型的 IO/通信都会给您带来麻烦。
您可以通过为应用程序逻辑使用简单的状态机来避免多线程和锁定。每当接收到数据时,状态机就会被触发并可以处理数据。如果所有数据都存在,您可以在应用程序中执行下一步。如果您愿意,您可以使用同步调用进行发送,因为它只会通过蓝牙系统丢弃数据。
Doing any kind of IO/communication in a synchronous way will get you into trouble.
You can avoid multi threading and locks by using a simple state machine for your application logic. Whenever data is received, the state machine is triggered and can process the data. If all data is there, you can do the next step in your app. You can use synchronous calls for sending if you like as it will just drop the data with the Bluetooth system.