2010-04-05 3 views
2

Я сделал несколько поисков по этой теме, но не нашел ничего ценного.Как защитить критический раздел в PHP?

Если я не использую обработчик сеанса PHP по умолчанию, на уровне запроса нет блокировки сеанса. Поэтому я должен сам защищать критический раздел.

В Java есть . В C# у нас есть блокировка.

В PHP, как это сделать?

+0

С каковой ситуацией вы занимаетесь? Я не уверен, о чем вы думаете, поскольку проблема связана с PHP. – cletus

+0

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

ответ

3

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

Если вы используете обработчик сеанса на основе файлов, вы можете попробовать базовый flock(). Если вы используете базу данных, вы можете попробовать использовать механизм блокировки двигателя (предпочтительно, на уровне строк). Если вы используете memcached, вы можете попробовать реализовать распределенную систему блокировки.

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

В мире баз данных (и в других местах) оптимистичные «блокировки» - это все, что вам нужно. Они включают в себя простой счетчик, который увеличивается. Если счетчик «выключен» (столкновение), запись не обновляется, и вы можете повторно выбирать и применять свои различия по мере необходимости. Это вещь типа UPDATE table WHERE count = lastcount в сочетании с повторением. Это часто делает трюк.

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

+0

Спасибо за ваш ответ. Я понимаю, что PHP не имеет нитевидной модели, такой как Java и C#.Но в тех же случаях я хочу, чтобы к одному объекту сеанса обращался только один обработчик запроса (в PHP, процесс или поток). Таким образом, вы предлагаете не сериализовать все поведение сеанса. Небольшая степень детализации блокировки приносит высокую производительность, но я просто сомневаюсь, что это сделает код сложным. Простое блокирование сеанса на уровне запросов (например, обработчик сеанса по умолчанию) глупо, но просто. –

+0

Это просто, конечно, но это немного лениво. Почему бы не заблокировать идентификатор сеанса? На одном сервере или окороченном облаке вы можете легко заблокировать некоторый файл '/ tmp/XXX' для каждого сеанса. Это практически решит вашу проблему. – pestilence669

0

В большинстве случаев вам не нужно иметь дело с критическим разделом, потому что PHP не имеет нить-модели (без обмена памятью). Я даже не думаю, что вам доступно semephores. PHP использует «Share-nothing Architecture», как вы можете видеть на слайдах PHP-создателя Расмуса Лердорфа. Это означает, что, как вы можете видеть на слайде, что

Общие данные проталкивается вниз к данных магазина слоя

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

Надеюсь, это немного ответит на ваш вопрос.

+0

Несмотря на то, что PHP не имеет ничего общего с архитектурой, переменные сеанса разделяются несколькими запросами. Существует еще возможный критический раздел. –

+0

Сессия делится между несколькими запросами, которые я предполагаю, но они являются безопасными стандартами? Как вы можете получить условия гонки? – Alfred

Смежные вопросы