Реализация многопоточности на php

334
02 апреля 2017, 05:29

Здравствуйте, есть задача реализовать перебор всех email из сайта и удалить несуществующие.

Есть такой код на php:

$str='test@gmail.com'; $alter=new CCheckMail(); print "E-mail: ".$str." - ".($alter->execute($str)?'существует':'не существует');

Class: https://pastebin.com/DnjGajXG

Время выполнения скрипта

1 проверка ~ 0.3634250164032

10 проверок ~ 3.5882749855518

100 проверок ~ 38.591406017542

В Базе ~ 4000000 почт и для этого понадобиться в лучшем случае 17 суток, что очень много.

Как реализовать многопоточность или может быть есть какие-то другие способы ускорить перебор?

Answer 1

В PHP есть несколько встроенных возможностей по управлению процессами (PCNTL , pthreads). скрипт можно распаралелить к примеру так :

//функция для отправки процесса в отдельную нить
function initThreads(array $callbacks) {
        foreach ($callbacks as $call) {
            $pid = pcntl_fork();
            if ($pid == 0) {
                $call();
                exit;
            }
        }
}
$callbacks = [];
// соберем тестовый массив с замыканиями , каждый из которых будет 
// выполнен асинхронно от другого
foreach(range(0, 10) as $thread){
    $callbacks[] = function()use( $thread ){
        print_r([
            'this thread' => $thread ,
            'this out' => implode(',',range(0 , $thread+1))
        ]);
    };
}
initThreads($callbacks); 

В данном примере все замыкания будут выполнены асинхронно , единственное надо учитывать кол-во порождаемых процессов и то что PCNTL будет работать только в CLI режиме.

Еще 1 способ заключается в асинхронном запуске через xargs , суть в том что бы передать в php параметр $argv , в твоем случае email адрес.

  • Создаем файл с email адресами 'emails'
  • запускаем xargs

< emails xargs -P 20 -n 1 -I % sh -c 'php thrun.php %'

тут мы считываем каждую строчку из файла и отправляем ее в наш обработчик. пусть будет thrun.php и передаем ему параметр %

в самом php обращаемся к этому параметру через $argv массив. далее ты пишеш свой обработчик который что-то там делает. Все получили асинхронный запуск обработчика для всех твоих email.

Answer 2

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

В простом php ничего подобного(без расширений) нет.
Вам может помочь:

  • Сервер очередей.
    Что-нибудь вроде RabbitMQ. Заполняете его своими миллионами задач, потом запускаете несколько воркеров(отдельных скриптов), которые по одному берут из очереди emailы и проверяют их. Больше воркеров(их можно запускать на разных машинах) - быстрее работа.

  • multicurl.
    Позволяет одновременно выполнять пачку http-запросов. Отправляете пачку запросов на скрипт обработчик, ждёте ответа от всей пачки.

  • Запросы в php-cli без stdout.
    С помощью exec('process_email.php email1@example.org 2>&1 >/dev/null') запускаете пачку скриптов без ожидания ответа. Скрипты проверяют свой диапазон email и сами помещают результаты в хранилище.
    Тут есть сложность с обратной связью, так что придётся изначально всё рассчитать:
    Например, запускаете 50 таких скриптов, каждый обрабатывает все email с id%50 == НомерСкрипта.

Возможно имеет смысл для подобной задачи взять другой инструмент(не php). Тот же nodejs, гораздо легче справится с подобной задачей.

READ ALSO
Подключить widget без bootstrap.css

Подключить widget без bootstrap.css

Разбираюсь с Yii2Можно ли как то использовать готовый виджет (к примеру https://github

278
Генерация формы множественного числа

Генерация формы множественного числа

Здравствуй, дали задачу по PHP

253
Объединиение или наследование C++

Объединиение или наследование C++

Всем привет, разрабатываю язык программирования на c++ (надо для учёбы), но в плюсах я пока новичок, и отсюда возникают различные вопросы из раздела...

312
Количество вхождений паттерна в строке C++

Количество вхождений паттерна в строке C++

Привет всем! Как посчитать количество вхождений паттерна regex в сроке? Язык С++

210