Как я выполняю сценарий n времена в то же время и как я моделирую семафор?

Безопасность: при открытии канала передачи нежелательные могут использовать его также. В частности, при использовании виртуальной машины для содержания недоверяемой операционной системы или приложения, гостевые дополнения представляют несколько рисков.

  • Существует больше кода во включении безопасности (доверяемая основа), так больше риска ошибок, которые могли позволить коду в виртуальной машине влиять на хост.
  • Дополнительные функции могут быть использованы для их намеченной цели, но непреднамеренным способом. Например, приложение в виртуальной машине может шпионить на всем содержании буфера обмена хоста.
3
12.01.2012, 19:57
3 ответа

Я предпочел бы управлять управлением числа с внешней стороны и просто называть сценарий, передающий его текущее число как параметр:

n=10
read nr < number.file
seq $((nr+1)) 120 | xargs -n 1 -P $n script.sh

Где сам сценарий был бы уменьшен до чего-то вроде этого:

#!/bin/ksh
number=$1
echo "Do job with/for number $number"
echo $number > number.file
sleep 10

Конечно, если продолжительность задачи может варьироваться, затем лучше для проверки текущего содержания файла числа прежде, чем записать в него, таким образом, не перезаписать больший. Но это важно, только если последовательность задач должна поддерживать вид возобновления.

2
27.01.2020, 21:20
  • 1
    , но это - параллелизм? потому что у меня должен быть тот же сценарий, работающий n времена, одновременно пытаясь отредактировать текстовый файл, хотя все процессы не могут отредактировать файл в то же время, они должны ожидать его очереди. –  Jasmin 12.01.2012, 22:23
  • 2
    Да, xargs'говорит о -P (--max-procs) опция: “Дошедший макс.-procs обрабатывает за один раз; значение по умолчанию равняется 1”. Так, чтобы код запустил процессы $n, передав следующий порядковый номер каждому как параметр. Как только один из процессов завершается, новый запускается, передавая его следующий порядковый номер. И так далее, пока последовательность чисел не закончена. –  manatwork 13.01.2012, 10:28
  • 3
    , я попробовал его, но... Я думаю, что seq не доступен на поле Unix, что я работаю, это говорит, что seq не нашел, и также-P опция xargs, это говорит, что это неизвестно. –  Jasmin 13.01.2012, 18:42
  • 4
    Извините, -P была сущность. Спасибо за то, что сообщили мне о его отсутствии на Unix. Другая команда, способная для выполнения параллельных задач, make с -j (--jobs) опция, но возможный быть расширением GNU. Так или иначе, мой make знание слишком слабо для создания этого ответом. –  manatwork 13.01.2012, 19:00

Выполнение этого без lockfile, казалось бы, потребовало бы чего-то странного, потому что lockfile (еще лучше, каталог блокировки, поскольку создание каталога, как предполагается, является атомарным) является стандартом и осуществимым решением этой проблемы. Я не сделал точно, что Вы хотите сделать, но здесь являетесь некоторыми идеями, которые происходят со мной:

Вы могли записать маленькую программу C для проверки состояния семафора SysV. Запустите с man semget или man semop. Это будет утомительно и причудливо.

Вы могли использовать Oracle sqlplus и блок МН / SQL, который делает:

lock table table_name in exclusive mode

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

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

Если можно загрузить модуль ядра, возможно, модуль ядра мог бы использовать a /proc виртуальный файл для действия как взаимное исключение или семафор. IBM developerWorks имеет статью о загружаемом модуле, который создает /proc файлы.

Возможно, Вы могли реализовать алгоритм Dekker со значениями в файлах или именованных каналах.

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

1
27.01.2020, 21:20
  • 1
    , который я вижу, но я должен сделать все в оболочке Korn, таким образом, я думаю, что это не то, что я ищу. Огромное спасибо также =) –  Jasmin 12.01.2012, 22:24
  • 2
    Можно выполнить sqlplus (интерпретатор SQL Oracle) из сценария оболочки. Я много раз делал это. Можно получить доступ к именованным каналам из сценария. Вы просто смогли делать Алгоритм Dekker из сценария оболочки, также. При исключении dir файла/блокировки блокировки необходимо сделать что-то странное, поскольку dir блокировки является обычным способом сделать материал. –  Bruce Ediger 13.01.2012, 03:20

Предположения:

  • Все Ваши экземпляры сценария работают на той же машине.
  • Существует известный каталог, где Ваш сценарий может записать, и что никакая другая программа не будет использовать. Этот каталог находится в “обычной” файловой системе (в частности, не NFS).

Можно использовать атомарные операции, такие как создание файла (set -C; (: >foo) 2>/dev/null), переименование (mv) и удаление (rm) обработать блокировку.

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

Во-первых, настройте каталог. Создайте названный файл lock и названный именованный канал pipe.

if ! [ -d /script-locking-directory ]; then
  # The directory doesn't exist, create and populate it
  {
    mkdir /script-locking-directory-$$ &&
    mkfifo /script-locking-directory-$$/pipe &&
    touch /script-locking-directory-$$/lock &&
    mv /script-locking-directory-$$ /script-locking-directory
  } || {
    # An error happened, so clean up
    err=$?
    rm -r /script-locking-directory-$$
    # Exit, unless another instance of the script created the directory
    # at the same time as us
    if ! [ -d /script-locking-directory ]; then exit $?; fi
  }
fi

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

take_lock () {
  while ! mv lock lock.held 2>/dev/null; do
    read <pipe # wait for a write on the pipe
  done
}
release_lock () {
  mv lock.held lock
  read <pipe & # make sure there is a reader on the pipe so we don't block
  echo >pipe # notify all readers
}

Эта схема будит всех официантов, которые могут быть неэффективными, но это не будет проблемой, если не будет много конкуренции (т.е. много официантов одновременно).

Основная проблема с кодом выше состоит в том, что, если держатель блокировки умирает, блокировка не будет выпущена. Как мы можем обнаружить ту ситуацию? Мы не можем только пойти, ища процесс, названный как блокировка из-за повторного использования PID. То, что мы можем сделать, открыть файл блокировки в сценарии и проверку, если файл блокировки открыт, когда новый экземпляр сценария запускается.

break_lock () {
  if ! [ -e "lock.held" ]; then return 1; fi
  if [ -n "$(fuser lock.held)" ]; then return 1; fi
  # If we get this far, the lock holder died
  if mv lock.held lock.breaking.$$ 2>/dev/null; then
    # Check that someone else didn't break the lock and take it just now
    if [ -n "$(fuser lock.breaking.$$)" ]; then
      mv lock.breaking.$$ lock.held
      return 0
    fi
    mv lock.breaking.$$ lock
  fi
  return 0 # whether we did break a lock or not, try taking it again
}
take_lock () {
  while ! mv lock lock.taking.$$ 2>/dev/null; do
    if break_lock; then continue; fi
    read <pipe # wait for a write on the pipe
  done
  exec 9<lock.taking.$$
  mv lock.taking.$$ lock.held
}
release_lock () {
  # lock.held might not exist if someone else is trying to break our lock.
  # So we try in a loop.
  while ! mv lock.held lock.releasing.$$ 2>/dev/null; do :; done
  exec 9<&-
  mv lock.releasing.$$ lock
  read <pipe & # make sure there is a reader on the pipe so we don't block
  echo >pipe # notify all readers
}

Эта реализация может все еще зайти в тупик, если держатель блокировки умирает, в то время как другой экземпляр внутри take_lock: блокировка останется сохраненной, пока третий экземпляр не запустится. Я также предполагаю, что сценарий не умрет внутри take_lock или release_lock.

Предупреждение: Я написал код выше непосредственно в браузере, я не протестировал его (уже не говоря о доказанном, который он исправляет).

1
27.01.2020, 21:20
  • 1
    это очень интересно. –  Jasmin 16.01.2012, 17:11
  • 2
    я - новичок в этом материале, таким образом, я учусь и иногда трудно мне понять. Таким образом, я имею некоторые вопросы блокировка и передаю файлы по каналу, что в них? take_lock я должен использовать его, прежде чем Это считало число? и release_lock после него пишут новое число? –  Jasmin 16.01.2012, 17:20
  • 3
    @Jasmin файл блокировки пуст. Его имя указывает, взята ли блокировка или нет. Вы звоните take_lock и release_lock вокруг критического раздела Вашего кода, как обычно, с блокировкой. –  Gilles 'SO- stop being evil' 16.01.2012, 20:19
  • 4
    хорошо, который я попробовал, но я получил некоторые ошибки: первое в этой строке, "если! [-d/script-locking-directory]; затем!" сказал не найденный, и я предполагаю, что это не входит в, если и не создают каталог, и по этой причине я думаю, что получил следующую ошибку: mv: lock.heid не может получить доступ: никакой такой файл или каталог –  Jasmin 16.01.2012, 22:51
  • 5
    @Jasmin я думаю, что Вы сделали ошибку при копировании кода. Я протестировал свой первый отрывок (не мой второй). lock.heid не появляется нигде в моем сообщении. спасибо –  Gilles 'SO- stop being evil' 16.01.2012, 23:01

Теги

Похожие вопросы