NSThread просыпается
Я хотел бы знать, как я могу достичь следующих целей-c,
Я делаю связь с модемом FTDI232R, используя последовательную связь, поэтому я использую вызов POSIX для открытия, записи и чтения по пути модема (dev/tty/nameOfModem). Вызовы POSIX - это синхронные вызовы, поэтому при чтении я не хочу блокировать мой основной поток, поэтому я думаю сделать вызов чтения в отдельном потоке.
Я не хочу, чтобы этот вторичный поток работал непрерывно, но просыпался только тогда, когда есть что прочитать, и после того, как чтение завершено, оно должно спать. Я просмотрел документацию и прочитал о предоставлении входного источника для NSRunLoop и добавлении этого цикла запуска к вторичный поток, но не мог понять, как это сделать.
Заранее спасибо за вашу помощь.
2 ответа
У вас обычно есть BOOL
чтобы указать состояние запуска, а затем дату до. При работе с сокетами я склонен делать что-то вроде:
NSDate *beforeDate = [NSDate dateWithTimeIntervalSinceNow:.1];
while (self.isActive && [[NSRunLoop currentRunLoop] runMode: NSRunLoopCommonModes beforeDate:beforeDate]) {
beforeDate = [NSDate dateWithTimeIntervalSinceNow:.1];
}
И затем, когда вы отключаетесь от вашего модема, вы можете установить isActive в NO, чтобы позволить циклу запуска замедляться.
Хотя это не совсем то , что вам нужно, документы Apple по работе с потоками с помощью NSOperation могут быть интересными для вас.
Для этого вам, вероятно, следует использовать источники рассылки GCD. Вот пример кода, скопированного непосредственно из этой статьи:
dispatch_source_t ProcessContentsOfFile(const char* filename)
{
// Prepare the file for reading.
int fd = open(filename, O_RDONLY);
if (fd == -1)
return NULL;
fcntl(fd, F_SETFL, O_NONBLOCK); // Avoid blocking the read operation
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,
fd, 0, queue);
if (!readSource)
{
close(fd);
return NULL;
}
// Install the event handler
dispatch_source_set_event_handler(readSource, ^{
size_t estimated = dispatch_source_get_data(readSource) + 1;
// Read the data into a text buffer.
char* buffer = (char*)malloc(estimated);
if (buffer)
{
ssize_t actual = read(fd, buffer, (estimated));
Boolean done = MyProcessFileData(buffer, actual); // Process the data.
// Release the buffer when done.
free(buffer);
// If there is no more data, cancel the source.
if (done)
dispatch_source_cancel(readSource);
}
});
// Install the cancellation handler
dispatch_source_set_cancel_handler(readSource, ^{close(fd);});
// Start reading the file.
dispatch_resume(readSource);
return readSource;
}