Прерывание заблокированных функций ввода/вывода

У меня есть поток, который читает последовательное устройство (/dev/ttyUSB0) и записывает данные в стандартный вывод:

void io_thread_func () {

    int serial_port = open(settings.port, O_RDWR);

    while (1) {

        char buf[100];

        int n = read(serial_port, buf, 100);

        fwrite(buf, 1, n, stdout);

    }

}

Как я могу прервать системный вызов «read (...)» из другого потока? Могу ли я вызвать «close(serial_port)» из другого потока, чтобы прервать все функции блокировки ввода-вывода? (Мне нужно прервать функции блокировки ввода-вывода, чтобы правильно закрыть поток)

Глеб: Рискну предположить, что Ваш вопрос практически идентичен stackoverflow.com/questions/3882379/… - Вы согласны?

Tony Delroy 24.12.2020 06:46

@TonyDelroy Непонятно, насколько полезен какой-либо из ответов.

Barmar 24.12.2020 07:12

Аналогичный вопрос, проверьте этот stackoverflow.com/questions/6910335/…

Krishna Kanth Yenumula 24.12.2020 07:16
int pthread_kill(pthread_t tid, int sig); отправляет сигнал sig другому потоку в том же процессе
Krishna Kanth Yenumula 24.12.2020 07:19

@Barmar: если это так, Глеб должен процитировать другой вопрос и сказать, как ответы были опробованы и потерпели неудачу для его цели (или предложить награду за лучшие решения существующего вопроса, но Глеб не может сделать это как новый участник - ни один из них не интернет-точка).

Tony Delroy 24.12.2020 07:28

есть ли системный вызов «interrupt_all_io_functions (int fd)»? или нет ?

gleb zheglov 24.12.2020 07:36

Сигналы posix (?) - единственный способ решить эту проблему?

gleb zheglov 24.12.2020 07:37
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я могу прервать системный вызов «read (...)» из другого потока? Могу ли я вызвать «close (serial_port)» из другого потока, чтобы прервать все функции блокировки ввода-вывода? (мне нужно прервать функции блокировки ввода-вывода, чтобы правильно закрыть поток)

Вы можете отправить сигнал потоку. Это прервет функцию read.

Вы абсолютно не можете закрыть последовательный порт из другого потока. Это может вызвать всевозможные бедствия. Учитывать:

  1. Эта ветка вот-вот позвонит read, но еще не позвонила.
  2. Другой поток вызывает close на serial_port.
  3. Прежде чем первый поток сможет вызвать read другой поток accepts входящее соединение сокета для критически важной внутренней цели системы.
  4. Этот поток получает тот же дескриптор, что и serial_port.
  5. Этот поток вызывает read, а затем fwrite, сбрасывая данные, полученные в критическом сокете, в stdout.

Хорошо, что это stdout. Потому что ошибка однажды вызвала точно такой же сценарий — за исключением того, что конфиденциальные данные были отправлены на случайные входящие соединения из Интернета, а не stdout.

есть ли системный вызов «interrupt_all_io_functions (int fd)»? или нет ?

gleb zheglov 24.12.2020 07:39

Сигналы posix (?) - единственный способ решить эту проблему?

gleb zheglov 24.12.2020 07:39

@glebzheglov Сигналы - это один из способов. Есть много других способов. В идеале вы просто не должны блокировать функцию, в которой не хотите ждать вечно. Например, вы можете poll использовать как последовательный порт, так и локальный сокет. Чтобы разблокировать вызов poll, вы можете просто отправить фиктивный байт в локальный сокет. Есть много способов сделать это.

David Schwartz 24.12.2020 23:24

Другие вопросы по теме