Как отличается вызов sync() и команда синхронизации

Я использовал mmap() с fopen ("/dev/mem"), чтобы создать сопоставление с блоком физической памяти, разделяемым между двумя процессорными ядрами в системе ARM. Когда процессор, работающий под управлением Linux, записывает память, может произойти отставание более чем на одну секунду до того, как другой не-Linux-процессор увидит записанные данные. Длительная задержка исчезает, если процесс Linux делает этот системный вызов сразу после записи в память:

System("sync; echo 3 > /proc/sys/vm/drop_caches");

Я попытался дублировать эту логику непосредственно в коде, но длительная задержка сохраняется:

Int fd; char* data = "3"; sync(); fd = open("/proc/sys/vm/drop_caches", O_WRONLY); write(fd, data, sizeof(char)); close(fd);

Почему вызов sync() отличается поведением от команды системы синхронизации? Эффект виртуальной памяти команды sync позволяет сбрасывать вызов sync()?

Я знаю, что в руководстве говорится, что программа синхронизации ничего не делает, кроме использования системного вызова sync (2), но влияет ли на то, что я вызываю sync() из пользовательского пространства? Он действует так, как если бы вызов синхронизации из пользовательского пространства просто планировал синхронизацию, а не блокировал ее до ее завершения.

2 ответов

Ты забыл новую линию.

echo 3 выходов "3\n" .

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

Каждый раз, когда вы вызываете команду sync-the-command или sync-the-system-call, вы вынуждаете ОС очищать каждую файловую систему на всем компьютере; хуже того, вы говорите операционной системе, чтобы забыть каждый буфер файловой системы, заставляя ОС перечитывать все с диска. Это ужасно для производительности для всей операционной системы практически так, как вы можете себе представить.

Существует гораздо более простой способ.

Используйте shm_open() для создания именованной области общей памяти. Используйте mmap для доступа к нему. Используйте блокировку памяти или общие/названные мьютексы только на этом фрагменте памяти, чтобы вы могли читать и писать последовательно и безопасно.

С точки зрения сложности ваш текущий подход, вероятно, в 1 000 000 раз дороже обычной памяти.

drop_caches нет ни drop_caches ни sync , так как оба они относятся к drop_caches файловой системы - на самом деле это не то, что вы здесь используете. Тот факт, что sync видимому, разрешает ее, вероятно, является совпадением. (Вероятно, это случайное удаление кэша данных при запуске инструмента sync).

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

mount

Выполняет монтирование файловой системы, обычно на устройстве со сменными носителями, такими как дискеты или CDROM. Файл /etc/fstab содержит перечень доступных для монтирования файловых систем, разделов и устройств, включая опции монтирования, благодаря этому файлу, монтирование может производиться автоматически или вручеую. Файл /etc/mtab содержит список смонтированных файловых систем и разделов (включая виртуальные, такие как /proc).

mount -a -- монтирует все (all) файловые системы и разделы, перечисленные в /etc/fstab , за исключением тех, которые имеют флаг noauto . Эту команду можно встретить в сценариях начальной загрузки системы из /etc/rc.d (rc.sysinit или нечто похожее).

Mount -t iso9660 /dev/cdrom /mnt/cdrom # Монтирование CDROM-а mount /mnt/cdrom # Более короткий и удобный вариант, если точка монтирования /mnt/cdrom описана в /etc/fstab

Эта команда может даже смонтировать обычный файл как блочное устройство. Достигается это за счет связывания файла с loopback-устройством . Эту возможность можно использовать для проверки ISO9660 образа компакт-диска перед его записью на болванку.

Пример 13-6. Проверка образа CD

# С правами root... mkdir /mnt/cdtest # Подготовка точки монтирования. mount -r -t iso9660 -o loop cd-image.iso /mnt/cdtest # Монтирование образа диска. # ключ "-o loop" эквивалентен "losetup /dev/loop0" cd /mnt/cdtest # Теперь проверим образ диска. ls -alR # Вывод списка файлов

umount

Отмонтирует смонтированную файловую систему. Перед тем как физически вынуть компакт-диск или дискету из устройства, это устройство должно быть отмонтировано командой umount , иначе файловая система может оказаться поврежденной (особенно это относится к накопителям на гибких магнитных дисках, прим. перев.).

Umount /mnt/cdrom # Теперь вы можете извлечь диск из привода.

sync

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

Иногда возникает необходимость принудительной синхронизации буферов ввода-вывода с содержимым на магнитном носителе, как, например, при надежном удалении файла (см. Пример 12-45) или когда наблюдаются скачки напряжения в сети электроснабжения.

losetup

Устанавливает и конфигурирует loopback-устройства .

Пример 13-7. Создание файловой системы в обычном файле

SIZE=1048576 # 1 Мб head -c $SIZE < /dev/zero > file # Создается файл нужного размера. losetup /dev/loop0 file # Файл назначается как loopback-устройство. mke2fs /dev/loop0 # Создание файловой системы. mount -o loop /dev/loop0 /mnt # Монтирование только что созданной файловой системы. # Спасибо S.C.

mkswap

Создание swap-раздела или swap-файла. Созданный swap-раздел (файл) нужно затем подключить командой swapon .

swapon , swapoff

Разрешает/запрещает использование swap-раздела (файла). Эта команда обычно используется во время загрузки системы или во время остановки.

mke2fs

Создает файловую систему ext2. Должна вызываться с правами суперпользователя.

Пример 13-8. Добавление нового жесткого диска

#!/bin/bash # Добавление в систему второго жесткого диска. # Программное конфигурирование. Предполагается, что устройство уже подключено к аппаратуре компьютера. # Взято из статьи автора документа. # "Linux Gazette", выпуск #38, http://www.linuxgazette.com. ROOT_UID=0 # Этот сценарий должен запускать только root. E_NOTROOT=67 # Код ошибки, если сценарий запущен простым пользователем. if [ "$UID" -ne "$ROOT_UID" ] then echo "Для запуска этого сценария вы должны обладать правами root." exit $E_NOTROOT fi # Будьте крайне осторожны! # Если что-то пойдет не так, то вы можете потерять текущую файловую систему. NEWDISK=/dev/hdb # Предполагается, что /dev/hdb -- это новое устройство. Проверьте! MOUNTPOINT=/mnt/newdisk # Или выберите иное устройство для монтирования. fdisk $NEWDISK mke2fs -cv $NEWDISK1 # Проверка на "плохие" блоки (bad blocks) и подробный вывод. # Обратите внимание: /dev/hdb1, *не* то же самое, что /dev/hdb! mkdir $MOUNTPOINT chmod 777 $MOUNTPOINT # Сделать новое устройство доступным для всех пользователей. # Теперь проаерим... # mount -t ext2 /dev/hdb1 /mnt/newdisk # Попробуйте создать каталог. # Если получилось -- отмонтируйте устройство и продолжим. # Последний штрих: # Добавьте следующую строку в /etc/fstab. # /dev/hdb1 /mnt/newdisk ext2 defaults 1 1 exit 0

tune2fs

Настройка отдельных параметров файловой системы ext2, например счетчик максимального количества монтирований без проверки. Должна вызываться с привилегиями пользователя root.

dumpe2fs

Выводит на stdout очень подробную информацию о файловой системе. Должна вызываться с привилегиями пользователя root.

Root# dumpe2fs /dev/hda7 | grep "ount count" dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 Mount count: 6 Maximum mount count: 20 hdparm

Выводит или изменяет параметры настройки жесткого диска. Должна вызываться с привилегиями пользователя root. Потенциально опасна при неправильном использовании.

fdisk

Создание или изменение таблицы разделов на устройствах хранения информации, обычно -- жестких дисках. Должна вызываться с привилегиями пользователя root.

fsck , e2fsck , debugfs

Набор команд для проверки, восстановления и отладки файловой системы.

fsck : интерфейсная утилита для проверки файловых систем в Unix (может вызывать другие утилиты проверки).

e2fsck : проверка файловой системы ext2.

debugfs : отладчик файловой системы ext2. Одно из применений этой универсальной (и опасной) утилиты -- это восстановление удаленных файлов. Только для опытных пользователей!

badblocks

Выполняет поиск плохих блоков (физические повреждения носителей) на устройствах хранения информации. Эта команда может использоваться для поиска плохих блоков при форматировании вновь устанавливаемых жестких дисков или для проверки устройств резервного копирования. Например, badblocks /dev/fd0 , проверит дискету на наличие поврежденных блоков.

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

lsusb , usbmodules

Команда lsusb выводит сведения о имеющихся в системе шинах USB (Universal Serial Bus) и подключенных к ним устройствах.

Команда usbmodules выводит информацию о модулях драйверов присоединенных USB-устройств.

Root# lsusb Bus 001 Device 001: ID 0000:0000 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.00 bDeviceClass 9 Hub bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0000 idProduct 0x0000 . . .

mkbootdisk

Создание загрузочной дискеты, которая может быть использована для загрузки системы, если, например, была повреждена MBR (master boot record -- главная загрузочная запись). Команда mkbootdisk -- это сценарий на языке командной оболочки Bash, chroot

CHange ROOT -- смена корневого каталога. Обычно, команды и утилиты ориентируются в файловой системе посредством переменной $PATH , относительно корневого каталога / . Команда chroot изменяет корневой каталог по-умолчанию на другой (рабочий каталог также изменяется). Эта утилита, как правило, используется с целью защиты системы, например, с ее помощью можно ограничить доступ к разделам файловой системы для пользователей, подключающихся к системе с помощью telnet (это называется -- "поместить пользователя в chroot окружение" ). Обратите внимание: после выполнения команды chroot изменяется путь к исполняемым файлам системы.

Команда chroot /opt приведет к тому, что все обращения к каталогу /usr/bin будут переводиться на каталог /opt/usr/bin . Аналогично, chroot /aaa/bbb /bin/ls будет пытаться вызвать команду ls из каталога /aaa/bbb/bin , при этом, корневым каталогом для ls станет каталог /aaa/bbb. Поместив строчку alias XX "chroot /aaa/bbb ls" в пользовательский ~/.bashrc , можно эффективно ограничить доступ команде "XX" , запускаемой пользователем, к разделам файловой системы.

lockfile

Эта утилита входит в состав пакета procmail (www.procmail.org). Она создает lock file , файл-семафор (или, если угодно, файл блокировки), который управляет доступом к заданному файлу, устройству или ресурсу. Lock file служит признаком того, что данный файл, устройство или ресурс "занят" некоторым процессом, и ограничивает (или вообще запрещает) доступ к ресурсу другим процессам.

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

Как правило, файлы блокировки создаются в каталоге /var/lock . Проверка наличия файла блокировки может быть проверена примерно таким образом:.

Appname=xyzip # Приложение "xyzip" создает файл блокировки "/var/lock/xyzip.lock". if [ -e "/var/lock/$appname.lock ] then ...

mknod

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

tmpwatch

Автоматически удаляет файлы, к которым не было обращений в течение заданного периода времени. Обычно вызывается демоном cron для удаления устаревших файлов системного журнала.

MAKEDEV

Утилита предназначена для создания файлов-устройств. Должна запускаться с привилегиями пользователя root, в каталоге /dev .

Root# ./MAKEDEV Это своего рода расширенная версия утилиты mknod .

Чтение с диска намного медленнее, по сpавнению с доступом к памяти (кроме виртуальных дисков (RAM disk), поскольку реально они создаются в памяти). К тому же довольно часто одна и та же часть диска считывается несколько pаз за относительно коpоткие пpомежутки вpемени. Напpимеp, может потpебоваться сначала считать электpонное сообщение, затем загpузить его в pедактоp пpи создании отзыва, после этого, пpогpамма обpаботки почты может пpочитать его еще pаз пpи копиpовании в папку. Путем однокpатного считывания инфоpмации с диска и ее последующего хpанения в памяти до тех поp, пока она больше не потpебуется, можно увеличить скоpость обмена, кpоме пеpвого считывания. Это называется дисковой буфеpизацией , а часть памяти, используемой для этих целей, дисковым буфеpом (кэшем) .

Так как объем памяти, к сожалению, огpаничен, то дисковый буфеp обычно не может быть очень больших pазмеpов. Когда буфеp пеpеполняется, то неиспользуемые данные стиpаются и память освобождается для дpугой инфоpмации.

Дисковая буфеpизация также pаботает и на запись. С одной стоpоны, записанные данные часто вскоpе считываются снова (напpимеp, исходный текст пpогpаммы записан в файл, а затем считан компилятоpом). С дpугой стоpоны, если данные только помещать в буфеp и не записывать их на диск, то это повышает скоpость обмена с диском пpогpамм, часто pаботающих с записью на диск. Запись данных может быть пpоизведена в фоновом pежиме, без замедления выполнения дpугих пpогpамм.

У большинства опеpационных систем существует дисковый буфеp (хотя он может называться по дpугому), но не все из них pаботают по описанным выше алгоpитмам. Некотоpые из них бывают с пpямой записью , т.е. данные записываются на диск сpазу (хотя, конечно, они хpанятся в буфеpе). Дpугие бывают с отложенной (иногда называют обpатной) записью , т.е. запись данных на диск пpоизводится позднее. Буфеpы с обpатной записью более эффективны, чем с пpямой, но и более склонны к ошибкам: пpи поломке компьютеpа или отключении питания, изменения, пpоизведенные в буфеpе, чаще всего теpяются. Это может пpивести к повpеждению файловой системы.

Поэтому не следует выключать питание компьютеpа без пpедваpительного запуска специальной пpоцедуpы завеpшения pаботы (см главу 6). Команда sync записывает содеpжимое буфеpа на диск для того, чтобы удостовеpится, что все данные пеpенесены на диск. В тpадиционных UNIX системах существует пpогpамма update , выполняющаяся в фоновом pежиме, котоpая выполняет команду sync каждые 30 секунд, поэтому обычно в ее пpименении нет необходимости. В системе Linux существует дополнительная пpогpамма-демон bdflush , котоpая выполняет команду sync не полностью и более часто во избежание внезапного замедления pаботы всей системы во вpемя обмена данными с диском, как это иногда случается со стандаpтной командой sync .

Под Linux bdflush запускается из update . Обычно нет никакой причины волноваться относительно этого, но если по некоторым причинам bdflush аварийно завершается, ядро предупредит относительно этого, и Вы должны запустить его вручную (/sbin/update ).

В действительности, буфеp хpанит не файлы, а блоки, котоpые являются наименьшей единицей обмена инфоpмацией с диском (в системе Linux один блок обычно pавен 1 KB). Таким же обpазом в буфеpе хpанятся каталоги, супеpблоки и дpугая инфоpмаация файловой системы, а также данные, считываемые с дисков, не имеющих файловой системы.

Эффективность буфеpизации в основном опpеделяется объемом буфеpа. Маленький буфеp пpактически не дает выигpыша: он хpанит настолько мало инфоpмации, что она стиpается пpежде чем может быть использована повтоpно. Кpитический pазмеp опpеделяется по объему считываемых и записываемых данных, а также как часто пpоизводится доступ к одинаковой инфоpмации. Подходящий для Вашей системы размер лучше всего найти опытным путем.

Если используется буфеp фиксиpованного объема, то его не следует менять, так как это может пpивести к значительному уменьшению свободной памяти и увеличению обмена данными между памятью и swap областью (что также замедляет pаботу системы). Для увеличения эффективности использования физической памяти, Linux автоматически использует весь ее свободный объем под буфеp и уменьшает его, если она тpебуется пpогpаммам.

В Linux не тpебуется выполнения каких-либо действий для обеспечения функциониpования дискового буфеpа. Его pабота контpолиpуется полностью автоматически за исключением того, что нужно следить за соответствующим выключением системы и быть внимательным пpи pаботе с дискетами.

НАЗВАНИЕ
sync - синхронизирует данные на диске с данными в памяти

СИНТАКСИС

sync [--help] [--version]

ОПИСАНИЕ
sync записывает данные, буферизованные в памяти, на диск.
Например, это могут быть измененные супер-блоки,
измененные inode, отложенные операции чтения и записи.
Буферизация должна быть реализована в ядре. Программа
sync всего лишь делает системный вызов sync(2).

Ядро хранит данные в памяти во избежание частых (обычно
медленных) дисковых операций чтения и записи. Это повышает
производительность, но если компьютер завершает работу во
внештатном режиме, то данные могут быть утеряны, либо
может быть повреждена файловая система. sync
гарантирует, что все, что хранилось в памяти, будет
записано на диск.

Sync должен вызываться перед тем, как система будет
остановлена каким-то нестандартным образом (например, если
при отладке ядра возникают неразрешимые проблемы). Обычно
система останавливается при помощи команд shutdown(8),
reboot(8), либо halt(8), которые переводят систему в
неактивное состояние, прежде чем вызывать sync(2).
(Существуют различные реализации этих команд; прочтите
документацию на вашу систему; в некоторых системах нельзя
непосредственно вызывать команды reboot(8) и halt(8).)

СТАНДАРТНЫЕ ОПЦИИ GNU
--help Выводит подсказку на устройство стандартного вывода
и успешно завершает работу.

Version
Выводит информацию о версии программы на устройство
стандартного вывода и успешно завершает работу.

Завершает список параметров.

ОКРУЖЕНИЕ
Переменные LANG, LC_ALL, LC_CTYPE и LC_MESSAGES имеют свое
обычное значение.

СООТВЕТСТВИЕ

POSIX 1003.2

ЗАМЕЧАНИЯ
В Linux sync гарантирует, что будет составлен список
"грязных" (dirty) блоков, которые нужно записать. Прежде
чем они действительно будут записаны, пройдет еще
некоторое время. Команды reboot(8) и halt(8) учитывают
это, делая паузу в несколько секунд после вызова sync(2).

Данная страница описывает версию sync из пакета fileu-
tils-4.0; другие версии могут немного отличаться.
Исправления и дополнения присылайте по адресу [email protected].
Отчеты об ошибках в этой программе присылайте по адресу
[email protected].