gpt4 book ai didi

cocoa - 如何关闭Cocoa后台线程中的串行通信

转载 作者:行者123 更新时间:2023-12-03 16:46:46 24 4
gpt4 key购买 nike

我正在尝试运行一个串行通信示例,以便按照 http://playground.arduino.cc/Interfacing/Cocoa 中提供的代码将数据从 Arduino 发送到 Cocoa 应用程序(IOKit/ioctl 方法)。它有效,但一旦启动我就无法停止接收器线程。

我实现了一个开关按钮(开始/停止),它在启动时打开串行端口并启动接收器线程:

- (IBAction) startButton: (NSButton *) btn {
(…)
error = [self openSerialPort: [SelectPort titleOfSelectedItem] baud:[Baud intValue]];
(…)
[self refreshSerialList:[SelectPort titleOfSelectedItem]];
[self performSelectorInBackground:@selector(incomingTextUpdateThread:) withObject:[NSThread currentThread]];
(…)
}

线程代码实际上与示例中的相同,只是我包含了从接收的缓冲区重建串行数据包并将其保存到 SQLite 数据库的代码:

- (void)incomingTextUpdateThread: (NSThread *) parentThread {

// mark that the thread is running
readThreadRunning = TRUE;

const int BUFFER_SIZE = 100;
char byte_buffer[BUFFER_SIZE]; // buffer for holding incoming data
int numBytes=0; // number of bytes read during read

(…)

// assign a high priority to this thread
[NSThread setThreadPriority:1.0];

// this will loop until the serial port closes
while(TRUE) {
// read() blocks until some data is available or the port is closed
numBytes = (int) read(serialFileDescriptor, byte_buffer, BUFFER_SIZE); // read up to the size of the buffer
if(numBytes>0) {
// format serial data into packets, but first append at start the end of last read
buffer = [[NSMutableString alloc] initWithBytes:byte_buffer length:numBytes encoding:NSASCIIStringEncoding];
if (status == 1 && [ipacket length] != 0) {
[buffer insertString:ipacket atIndex:0];
numBytes = (int) [buffer length];
}
ipacket = [self processSerialData:buffer length:numBytes]; // Recompose data and save to database.
} 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;

}

我尝试使用以下代码关闭主线程中的端口,该代码也是 startButton 选择器的一部分,遵循提供的示例:

if (serialFileDescriptor != -1) {
[self appendToIncomingText:@"Trying to close the serial port...\n"];
close(serialFileDescriptor);
serialFileDescriptor = -1;

// Revisar... crec que el thread no s'adona que s'ha tancat el file descriptor...
// wait for the reading thread to die
while(readThreadRunning);
// re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec
sleep(0.5);

//[btn setTitle:@"Start"];
[Start setTitle:@"Start"];
}

但是接收线程似乎不知道全局变量serialFileDescriptor的状态变化。

最佳答案

那么,startButton: 打开端口,生成一个线程以开始从中读取数据,然后立即关闭端口?结果不会很好。

startButton: 不应关闭端口。完成后将其留给读取线程执行,仅当您因其他原因(例如退出)需要关闭端口时才在主线程上执行此操作。

根据定义,全局变量在整个程序中都是可见的,这包括跨线程边界。如果 readThreadRunning 未设置为 FALSE(假设 FALSE 尚未定义为外来的东西),那么您的读取线程的循环必须仍在运行。要么仍在读取数据,要么读取被阻塞(正在等待更多数据)。

请注意,read无法知道是否会有更多数据。正如代码中的注释所述,它将阻塞,直到它有一些数据要返回或端口关闭为止。您应该想出一种方法来提前知道需要读取多少数据,并在读完那么多数据后停止,或者看看是否可以在所有内容都发送完毕后关闭另一端的端口,已收到。

关于cocoa - 如何关闭Cocoa后台线程中的串行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14957463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com