[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Многопоточность в PHP (Размышления)
I++
Итак код (эксперементальный):


<?php
$main = new MainLoop();
$main->start();

$file = new FileFetcher('news.txt'); // файл из дистра php 357 kb
$file->start();
$file->notify();
$file->wait();

while(!$file->feof){
$file->fetch();
echo 'Data fetched'."\n";
$file->notify();
$file->wait();
}

class MainLoop extends Thread
{
public function run()
{
while(true)
{
$time = microtime(true);
usleep(100000); // 99 ms // 0.1 sec
echo 'Time: '.(int)((microtime(true) - $time) * 1000)." ms\n";
}
}
}


class FileFetcher extends Thread
{
public function __construct($file)
{
$this->file = $file;
$this->fd = fopen($this->file, 'r');
}

public function run()
{
$this->feof = feof($this->fd);

while(!$this->feof){
$time = microtime(true);
$this->data = fread($this->fd, 1024);
sleep(1);
echo 'Data read time: '.(int)((microtime(true) - $time) * 1000)." ms\n";
$this->notify();
$this->wait();
$this->feof = feof($this->fd);
}
}


protected function fetch()
{
$data = $this->data;
$this->data = null;
return $data;
}

protected function feof()
{
return $this->feof;
}
}


Теперь о том, что я получил на выходе:

Data read time: 999 ms
Time: 99 ms
Data fetched
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Data read time: 999 ms
Time: 99 ms
Data fetched
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Data read time: 999 ms
Time: 99 ms
Data fetched
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Time: 99 ms
Data read time: 999 ms
Time: 99 ms
Data fetched


Оно работает!

Теперь главный вопрос нахрена это упало?

Представим у вас есть приложение демон (да вы извращенец пишите демонов на php)

И в вашем демоне есть полноценные сокеты и свой протокол, к примеру вы хотите запросить файл клиентом со своего сервера, но кто уже так делал знают, что при операциях с файлами используя fread, fgets и другие функции например dio (если вы работаете с крупными файлами и вам не хочется, забивать кеш ибо попадание в кеш при файловых операциях в вашем демоне стремится к нулю), основной поток замораживается и создается задержка. Даже если вести чтение мелкими блоками, что очень не эффективно, задержка уменьшается.

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

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

И тут у меня 3 потока в общей сложности.

1. Основной поток php
2. MainLoop
3. FileFetcher.

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

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.