Мне нужно использовать мьютексы или семафоры в PHP, и это меня пугает.Чтобы уточнить, я не боюсь писать код без взаимоблокировок, который синхронизируется должным образом, или боится рисков параллельного программирования, а также того, насколько хорошо PHP обрабатывает незначительные случаи.
Краткий обзор: написание интерфейса обработчика кредитной картыкоторый находится между пользователями и сторонним шлюзом кредитных карт.Необходимо предотвратить повторяющиеся запросы, и уже есть система, которая работает, но если пользователь нажимает кнопку submit (без JS, поэтому я не могу отключить кнопку для них) с интервалом в миллисекунды, возникает условие гонки, где мой PHP-скриптне понимает, что был сделан повторный запрос.Нужен семафор / мьютекс, чтобы я мог обеспечить выполнение только одного успешного запроса для каждой уникальной транзакции.
Я запускаю PHP за nginx через PHP-FPM с несколькими процессами на многоядерной машине Linux.Я хочу быть уверен, что семафоры
- совместно используются всеми процессами php-fpm и всеми ядрами (ядром i686).
- php-fpm обрабатывает сбой процесса PHP при удержанииmutex / семафор и освобождает его соответственно.
- php-fpm обрабатывает прерывание сеанса, удерживая мьютекс / семафор, и освобождает его соответственно.
Да, я знаю.Очень простые вопросы, и было бы глупо думать, что для любого другого программного обеспечения не существует правильного решения.Но это PHP, и он, скорее всего, не был создан с учетом параллелизма, он часто дает сбой (в зависимости от того, какие расширения вы загрузили) и находится в нестабильной среде (PHP-FPM и в Интернете).
Что касается (1), я предполагаю, что если PHP использует функции POSIX, оба эти условия выполняются на машине SMP i686.Что касается (2), из краткого просмотра документов я вижу, что есть параметр, который определяет это поведение (хотя почему бы PHP никогда не освобождать мьютекс, если сеанс уничтожен, я не понимаю).Но (3) это моя главная проблема, и я не знаю, можно ли предположить, что php-fpm правильно обрабатывает все дополнительные случаи для меня.Я (очевидно) никогда не хочу тупиков, но я не уверен, что могу доверять PHP, чтобы он никогда не оставлял мой код в состоянии, когда он не может получить мьютекс, потому что сеанс, который захватил его, был либо изящно, либо изящно завершен.
Я рассмотрел использование подхода MySQL LOCK TABLES
, но здесь есть еще больше сомнений, потому что, хотя я доверяю блокировке MySQL больше, чем блокировке PHP, я боюсь, что PHP прерывает запрос (с * out * crash), покаудерживая блокировку сеанса MySQL, MySQL может держать таблицу заблокированной (особенно потому, что я легко могу представить код, который может вызвать это).
Честно говоря, мне было бы наиболее удобно с очень простым Cрасширение, в котором я могу точно узнать, какие вызовы POSIX выполняются и с какими параметрами обеспечить точное поведение, которое я хочу ... но я не с нетерпением жду написания этого кода.
У кого-нибудь есть какой-либо лучший связанный с параллелизмомпрактики, касающиеся PHP, которыми они хотели бы поделиться?