C потоковых операций файловой системы: к ftw () или к fts_open ()? - PullRequest
0 голосов
/ 24 мая 2018

Предположим, что многопоточная программа выполняет операции с файловой системой (обход, чтение, создание, удаление, перемещение каталогов и файлов).

Согласно ответ , ftw() небезопасен в этомситуация.(Кроме того, ftw() требует глобальных переменных, что не выглядит слишком элегантно.)

Стоит ли вместо этого использовать fts_open() / fts_children() / fts_read()?Или, возможно, scandir()?

Что небезопасно в многопоточной программе, использующей ftw() (где один поток использует ftw() для агрегирования данных, а другой поток удаляет / перемещает некоторые данные), точнои почему?

1 Ответ

0 голосов
/ 13 апреля 2019

Преобразование комментариев в ответ.

Если один поток выполняет chdir(), в то время как другой поток выполняет ftw() (или nftw()), весь ад может вырваться на свободу.Удаление каталога во время его сканирования может также вызвать проблемы (но это может произойти из другого процесса, не говоря уже о других потоках).

Является ли переносимость проблемой?Набор функций fts(3) может быть доступен не везде (BSD / macOS помечает его как «ожидаемый для включения в будущую редакцию стандарта IEEE Std 1003.1-1988 ('POSIX.1')», что улучшаетего шансы быть переносимым, но не гарантируют его - его нет в POSIX 2018 (см. ниже) .

Возможно, вам придется использоватьFTS_NOCHDIR, если вы работаете с многопоточным приложением или внимательно относитесь к использованию функций *at() для доступа к файлам.

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

Не знаю, нужно ли менять каталогэто единственный способ столкнуться с проблемами, это всего лишь один довольно важный способ, которым все может быть испорчено. Если у вас два потока или два процесса в работе, один пытается сканировать файловую систему с помощью fts_read() и др.а также другой вносит произвольные изменения (например, перемещает каталог из одной позиции в дереве в другую), и тогда я вижу все возможности путаницы в учете, выполняемом сканирующим кодом - пропуская то, что должно было быть подсчитано, считая вещидважды, который должен был быть посчитан только один раз.

Я собираюсь упомянуть nftw(), потому что иначе он не обнаружился.Он имеет несколько преимуществ перед ftw(), но безопасность потоков не является одним из них.Следовательно, это в основном не касается, поскольку проблемы, которые затрагивают fts_read() и ftw(), также затрагивают nftw().

Обратите внимание, что scandir() читает и выбирает содержимое одногокаталог без пересечения иерархии.Он предназначен для другой работы от ftw() и друзей.Это не простая замена для ftw() и др.

Похоже, fts(3) был рассмотрен, но отклонен для POSIX: http://www.opengroup.org/platform/ballots/1003.1a.d14.crb.txt

...