Насколько надежны потоки pipe () и socket ()?(проблема двойного закрытия ()) - PullRequest
0 голосов
/ 23 июня 2019

Я использую g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
uname -a Linux ubuntu 4.18.0-17-generic #18~18.04.1-Ubuntu SMP Fri Mar 15 15:27:12 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Я думал, что все системные вызовы, которые создают файловые дескрипторы, являются поточно-ориентированными на Linux. Я имею в виду, что одновременный вызов socket() и pipe() из разных потоков не должен возвращать один и тот же fd. Разве это не правда?

Ответы [ 2 ]

1 голос
/ 23 июня 2019

В вашем примере программы у вас есть гонок данных на каждую из ваших глобальных переменных, кроме pI и sI.Вы читаете их из одной ветки, а пишете им из другой.Это приводит к неопределенному поведению, означающему, что любой результат, который вы получаете из этой программы, не имеет смысла.

Обе функции socket и pipe являются поточно-ориентированными, а также безопасно использовать от асинхронных обработчиков сигналов.Как ни странно, справочные страницы не содержат такой информации, а онлайн-документация -.

0 голосов
/ 24 июня 2019

Это не так справедливо, потому что я действительно не показывал никакого реального кода, но я хочу ответить на свой вопрос ради других пользователей.

  • Симптомы, которые я видел, были такими ошибками, как
    • errno 9 (Bad file descriptor)
    • Мёртвая блокировка приложения (из-за связи с другими процессами по некорректным дескрипторам файлов)
  • Это многопоточная среда.
  • Я начал сомневаться в том, что socket() и pipe() не являются многопоточными безопасными из-за журналов, которые я добавил для отладки.Я видел один и тот же fd, используемый двумя разными потоками одновременно (я не помещал логи во все соответствующие места, поэтому я видел это странное происшествие).
  • Благодаря этому Двойное закрытие() абзац, я понял, что это была вариация моей проблемы:
    • Тема 1 open() fd 100
    • Тема 1 close() fd 100. Закрыть # 1 <--- это была ошибка </strong>
    • Поток 2 open() fd 100 (теперь совершенно нормально, когда 100 не используется ни одним потоком в процессе)
    • Тема 1 close() снова fd 100. Close # 2.
      • Эта секунда close() фактически закрывает fd 100 потока 2. Затем, когда поток 2 использует этот fd, он получит errno 9 (Bad file descriptor) за использование закрытого fd,
      • Это может также стать более сложным: в этот момент fd 100 закрывается.Он может быть повторно открыт другим потоком, который использует его с read()/write().Поток 2 будет использовать его также с read()/write() - этот сценарий, когда два потока используют один и тот же fd, неверен и делает недействительными данные, отправленные / полученные на этом fd.
...