Avatar ·

Что такое thread safe и non-thread safe в PHP? Как выбрать правильную версию?

Всем привет! Я новичок в PHP, и при скачивании дистрибутива PHP с официального сайта я вижу две версии: "Thread Safe" (TS) и "Non-Thread Safe" (NTS). Честно говоря, я не понимаю разницы и не знаю, какую из них выбрать. Я использую XAMPP на Windows и пишу простые сайты. Но недавно я попробовал написать скрипт, который отправляет email-уведомления в цикле. Вот упрощенный код: ```php ``` Когда я запускаю этот скрипт, страница грузится очень долго, и я подумал, что можно было бы ускорить процесс с помощью потоков (threads). Я нашел расширение pthreads, но оно требует Thread Safe версию PHP. Однако я читал, что если использовать Apache с модулем mod_php, то тоже нужно выбирать Thread Safe. А для Nginx или командной строки — Non-Thread Safe. У меня несколько вопросов: 1. Что вообще означают эти термины простыми словами? 2. Как понять, какая версия установлена у меня сейчас? 3. Если я ошибусь с выбором, это сломает мой сайт или просто не будет работать какое-то расширение? 4. Для чего вообще нужна многопоточность в PHP, если он и так обрабатывает запросы параллельно через Apache? Буду благодарен за подробное объяснение с примерами! <<>>

Что такое Thread Safe и Non-Thread Safe в PHP?

Thread Safe (TS) — это версия PHP, которая может безопасно работать в многопоточной среде, где несколько потоков выполняются одновременно и могут обращаться к одним и тем же данным. Non-Thread Safe (NTS) — версия, оптимизированная для работы с одним потоком на процесс, что делает её быстрее, но небезопасной при использовании потоков внутри самого PHP.

Как это работает на практике?

Представьте, что PHP — это кухня, а каждый запрос к серверу — это повар.

  • Apache с модулем mod_php (MPM prefork): Каждый повар работает на своей отдельной кухне. Они не мешают друг другу — это Non-Thread Safe режим. PHP-скрипты выполняются в отдельных процессах, и нет риска, что один процесс испортит данные другого.
  • Apache с модулем mod_php (MPM worker или event): Все повары работают на одной большой кухне, делят общие инструменты (ножи, кастрюли). Если один повар положит нож не на место, другой может пораниться. Чтобы этого избежать, нужна Thread Safe версия PHP, которая блокирует доступ к общим ресурсам (например, к глобальным переменным или функциям вроде mail()).

Когда выбирать Thread Safe (TS)?

Выбирайте TS, если:

  • Используете Apache с MPM worker или event (многопоточная модель).
  • Планируете использовать расширение pthreads для создания потоков внутри PHP-скрипта (например, для параллельной обработки задач).
  • Работаете с IIS в режиме FastCGI (некоторые конфигурации требуют TS).

Пример скрипта с pthreads (требует TS):

<?php
class WorkerThread extends Thread {
    public function run() {
        // Тяжелая задача
        mail("user@example.com", "Поток", "Сообщение");
    }
}

$threads = [];
for ($i = 0; $i < 5; $i++) {
    $threads[] = new WorkerThread();
    $threads[$i]->start();
}
foreach ($threads as $thread) {
    $thread->join();
}
echo "Письма отправлены параллельно!";
?>

Когда выбирать Non-Thread Safe (NTS)?

Выбирайте NTS, если:

  • Используете Nginx + PHP-FPM (самый популярный вариант).
  • Работаете с Apache + mod_php в режиме MPM prefork (процессный, а не поточный).
  • Запускаете PHP-скрипты из командной строки (CLI) — там нет многопоточности.
  • Используете современные фреймворки (Laravel, Symfony) — они обычно работают через PHP-FPM.

Важно: NTS версия работает быстрее TS, потому что не тратит ресурсы на блокировки (mutex, semaphore). Если вы не используете pthreads и не работаете с многопоточным Apache, берите NTS.

Как проверить, какая версия установлена?

Создайте файл info.php с содержимым:

<?php phpinfo(); ?>

Откройте его в браузере. Найдите строку "Thread Safety":

  • enabled — у вас Thread Safe.
  • disabled — у вас Non-Thread Safe.

Что будет, если ошибиться?

Если вы установите TS версию для Nginx + PHP-FPM (который однопоточный), сайт будет работать, но чуть медленнее из-за лишних блокировок. Если же вы установите NTS версию для многопоточного Apache, то получите ошибки, падения и нестабильную работу, особенно при использовании расширений вроде pthreads. В худшем случае — белый экран смерти (WSOD).

Рекомендация

Для 90% современных проектов берите Non-Thread Safe (NTS). Используйте связку Nginx + PHP-FPM — это быстрее, безопаснее и проще в настройке. Thread Safe нужен только для специфических задач (многопоточные расширения, старый Apache с worker MPM).

<<>>

Дополнительный взгляд: когда TS всё-таки нужен

Коллега выше отлично объяснил основы. Хочу добавить важный нюанс: даже если вы используете Nginx + PHP-FPM, некоторые расширения могут требовать Thread Safe версию. Например:

  • pthreads (создание потоков внутри PHP) — только TS.
  • parallel (современная альтернатива pthreads) — тоже требует TS.
  • Zend OpCache — работает с обеими версиями, но есть баги в старых сборках NTS.

Если вы пишете парсер, который должен обрабатывать 1000 URL-адресов параллельно, и не хотите использовать очереди (RabbitMQ, Redis), то TS + pthreads — ваш выбор. Пример с parallel (PHP 7.4+):

<?php
use parallel\Runtime;

$runtimes = [];
for ($i = 0; $i < 5; $i++) {
    $runtimes[] = new Runtime();
    $runtimes[$i]->run(function($id) {
        // Параллельная отправка email
        mail("user@example.com", "Поток $id", "Тест");
    }, [$i]);
}
?>

Однако помните: многопоточность в PHP — это сложно. Для большинства задач лучше использовать асинхронные очереди (Gearman, RabbitMQ) или встроенные функции вроде curl_multi_exec(). Они не требуют TS и работают стабильнее.

Итог: Если вы новичок — ставьте NTS. Если знаете, зачем вам TS — ставьте TS. В XAMPP по умолчанию обычно идёт TS, но для продакшена рекомендую перейти на Nginx + PHP-FPM с NTS.