Czy PHP obsługuje wątki?

131

Znalazłem ten pakiet PECL zwany wątkami , ale nie ma jeszcze wydania. I nic się nie pojawia na stronie PHP.

Thomas Owens
źródło
Czy ktoś wie, czy this ( pcntl_fork()) zadziała, jeśli zostanie wywołane z Apache?
Josh K
To jest niewiarygodnie stare, ale mam odpowiedź, która faktycznie zapewnia wątki w php (zobacz poniżej linki).
Alec Gorge
Zalecają, aby nie wywoływać forka ze środowiska serwera. Nie winię ich. Jednak pcntl_fork wydaje się być najlepszym rozwiązaniem do tworzenia wątków w PHP.
just_wes
Tak, nie powinieneś potrzebować rozwidlać procesu apache2 php.
andho
2
Używanie pthreads działa jak urok
Baba

Odpowiedzi:

40

Nie ma nic, czego jestem świadomy. Następną najlepszą rzeczą byłoby po prostu wykonanie jednego skryptu przez inny przez CLI, ale to trochę podstawowe. W zależności od tego, co próbujesz zrobić i jak jest to skomplikowane, może to być opcja lub nie.

Wilco
źródło
1
Tak myślałem. Widziałem kilka starszych postów mówiących „nie” i nic na php.net, więc to była moja myśl. Dzięki za potwierdzenie.
Thomas Owens,
2
Tak, ten pakiet PECL jest trochę drażniący - też go spotkałem, ale nic z tego nie wyszło.
Wilco
183

Z podręcznika PHP dla rozszerzenia pthreads :

pthreads to zorientowany obiektowo interfejs API, który umożliwia wielowątkowość w PHP z poziomu użytkownika. Zawiera wszystkie narzędzia potrzebne do tworzenia wielowątkowych aplikacji przeznaczonych dla sieci WWW lub konsoli. Aplikacje PHP mogą tworzyć, czytać, pisać, wykonywać i synchronizować z wątkami, elementami roboczymi i stosami.

Choć brzmi to niewiarygodnie, jest to całkowicie prawdziwe. Dzisiaj PHP może obsługiwać wiele wątków dla tych, którzy chcą go wypróbować.

Pierwsze wydanie PHP4, 22 maja 2000 r., PHP zostało dostarczone z architekturą bezpieczną dla wątków - sposobem na wykonywanie wielu instancji swojego interpretera w oddzielnych wątkach w wielowątkowych środowiskach SAPI (Server API). W ciągu ostatnich 13 lat projekt tej architektury był utrzymywany i udoskonalany: od tamtej pory jest ona używana do produkcji na największych stronach internetowych na świecie.

Wątkowanie w obszarze użytkownika nigdy nie było problemem dla zespołu PHP i tak pozostaje do dziś. Powinieneś zrozumieć, że w świecie, w którym PHP prowadzi swoją działalność, istnieje już zdefiniowana metoda skalowania - dodaj sprzęt. Przez wiele lat istniał PHP, sprzęt stał się coraz tańszy, więc zespół PHP coraz mniej się tym przejmował. Choć stawał się coraz tańszy, stawał się też znacznie potężniejszy; obecnie nasze telefony komórkowe i tablety mają architekturę dwu- i czterordzeniową oraz dużą ilość pamięci RAM, nasze komputery stacjonarne i serwery mają zwykle 8 lub 16 rdzeni, 16 i 32 gigabajty pamięci RAM, chociaż nie zawsze możemy mieć dwa w ramach budżetu i posiadanie dwóch komputerów stacjonarnych rzadko jest przydatne dla większości z nas.

Dodatkowo PHP zostało napisane dla nie-programistów, jest to język ojczysty wielu hobbystów. Powodem, dla którego PHP jest tak łatwo przyswajalny, jest to, że jest to łatwy do nauki i pisania język. Powodem, dla którego PHP jest dziś tak niezawodny, jest ogromna ilość pracy włożona w jego projekt i każda decyzja podjęta przez grupę PHP. Jego niezawodność i czysta wielkość sprawiają, że po tych wszystkich latach jest w centrum uwagi; gdzie jego rywale ulegli czasowi lub presji.

Programowanie wielowątkowe nie jest łatwe dla większości, nawet przy najbardziej spójnym i niezawodnym API, są różne rzeczy do przemyślenia i wiele nieporozumień. Grupa PHP nie chce, aby wielowątkowość użytkowników była podstawową funkcją, nigdy nie poświęcono jej poważnej uwagi - i słusznie. PHP nie powinno być skomplikowane dla każdego.

Biorąc wszystko pod uwagę, nadal istnieją korzyści wynikające z umożliwienia PHP wykorzystania gotowych do produkcji i przetestowanych funkcji, aby umożliwić maksymalne wykorzystanie tego, co mamy, gdy dodawanie więcej nie zawsze jest opcją, i to za dużo zadań nigdy nie jest naprawdę potrzebne.

pthreads zapewnia, dla tych, którzy chcą go poznać, interfejs API, który pozwala użytkownikowi na wielowątkowe aplikacje PHP. Jego API jest w dużej mierze w toku i wyznaczyło poziom beta stabilności i kompletności.

Powszechnie wiadomo, że niektóre biblioteki używane przez PHP nie są bezpieczne dla wątków. Dla programisty powinno być jasne, że pthreads nie może tego zmienić i nie próbuje tego robić. Jednak każda biblioteka, która jest bezpieczna dla wątków, jest użyteczna, tak jak w każdej innej konfiguracji interpretera bezpiecznej wątkowo.

pthreads wykorzystuje wątki Posix (nawet w systemie Windows), co tworzy programista, to prawdziwe wątki wykonania, ale aby te wątki były użyteczne, muszą znać PHP - być w stanie wykonywać kod użytkownika, udostępniać zmienne i umożliwiać użyteczne środki komunikacji (synchronizacja). Tak więc każdy wątek jest tworzony za pomocą wystąpienia interpretera, ale zgodnie z projektem jego interpreter jest odizolowany od wszystkich innych wystąpień interpretera - podobnie jak wielowątkowe środowiska API serwera. pthreads próbuje wypełnić lukę w rozsądny i bezpieczny sposób. Wiele obaw programistów wątków w C po prostu nie dotyczy programistów pthreads, z założenia pthreads jest kopiowany podczas odczytu i kopiowania podczas zapisu (pamięć RAM jest tania), więc żadne dwie instancje nigdy nie manipulują tymi samymi danymi fizycznymi , ale oba mogą wpływać na dane w innym wątku.

Dlaczego kopiować podczas czytania i kopiowania podczas pisania:

public function run() {
    ...
    (1) $this->data = $data;
    ...
    (2) $this->other = someOperation($this->data);
    ...
}

(3) echo preg_match($pattern, $replace, $thread->data);

(1) Podczas gdy blokada odczytu i zapisu jest utrzymywana w składnicy danych obiektu pthreads, dane są kopiowane z pierwotnej lokalizacji w pamięci do składnicy obiektów. pthreads nie dostosowuje refcount zmiennej, Zend jest w stanie zwolnić oryginalne dane, jeśli nie ma do nich dalszych odniesień.

(2) Argument someOperation odwołuje się do składnicy obiektów, pierwotne przechowywane dane, które same są kopią wyniku (1), są ponownie kopiowane dla silnika do kontenera zval, podczas gdy to zachodzi blokada odczytu składnicy obiektów, blokada zostaje zwolniona i silnik może wykonać funkcję. Kiedy tworzony jest zval, ma odniesienie równe 0, co umożliwia silnikowi zwolnienie kopii po zakończeniu operacji, ponieważ nie istnieją żadne inne odniesienia do niego.

(3) Ostatni argument preg_match odwołuje się do magazynu danych, uzyskuje się blokadę odczytu, dane ustawione w (1) są kopiowane do wartości zval, ponownie z liczbą referencyjną równą 0. Blokada zostaje zwolniona, wywołanie preg_match działa na kopia danych, która sama w sobie jest kopią oryginalnych danych.

Rzeczy, które warto wiedzieć:

  • Tablica skrótów
    składnicy obiektów, w której przechowywane są dane, bezpieczna wątkowo , jest oparta na tabeli TsHashTable dostarczanej z PHP przez firmę Zend.

  • Składnica obiektów ma blokadę odczytu i zapisu, dodatkowa blokada dostępu jest zapewniona dla TsHashTable, tak że jeśli wymaga (i ma, var_dump / print_r, bezpośredni dostęp do właściwości, ponieważ silnik PHP chce się do nich odwołać) pthreads mogą manipulować TsHashTable poza zdefiniowanym API.

  • Blokady są utrzymywane tylko wtedy, gdy wykonywane są operacje kopiowania, po wykonaniu kopii blokady są zwolnione, w rozsądnej kolejności.

To znaczy:

  • W przypadku zapisu zachowywana jest nie tylko blokada odczytu i zapisu, ale także dodatkowa blokada dostępu. Sama tabela jest zablokowana, nie ma możliwości, aby inny kontekst mógł ją zablokować, odczytać, zapisać lub wpłynąć na nią.

  • Kiedy następuje odczyt, nie tylko blokada odczytu jest utrzymywana, ale także dodatkowa blokada dostępu, ponownie stół jest blokowany.

Żadne dwa konteksty nie mogą fizycznie ani jednocześnie uzyskiwać dostępu do tych samych danych w składnicy obiektów, ale zapisy wykonane w dowolnym kontekście z odwołaniem wpłyną na dane odczytane w dowolnym kontekście z odwołaniem.

Nie ma wspólnej architektury, a jedyną drogą do istnienia jest współistnienie. Ci trochę bystrzy zobaczą, że dużo się tu kopiuje i będą się zastanawiać, czy to dobrze. Całkiem dużo kopiowania odbywa się w dynamicznym środowisku wykonawczym, to jest dynamika dynamicznego języka. pthreads jest implementowany na poziomie obiektu, ponieważ można uzyskać dobrą kontrolę nad jednym obiektem, ale metody - kod wykonywany przez programistę - mają inny kontekst, wolny od blokowania i kopiowania - lokalny zasięg metody. Zasięg obiektu w przypadku obiektu pthreads należy traktować jako sposób na współdzielenie danych między kontekstami, czyli taki jest jego cel. Mając to na uwadze, możesz zastosować techniki pozwalające uniknąć blokowania składnicy obiektów, chyba że jest to konieczne,

Większość bibliotek i rozszerzeń dostępnych dla PHP to cienkie opakowania innych firm, podstawowe funkcje PHP do pewnego stopnia są tym samym. pthreads nie jest cienką owijką wokół Posix Threads; jest to interfejs API do obsługi wątków oparty na Posix Threads. Nie ma sensu implementowanie wątków w PHP, których użytkownicy nie rozumieją lub nie mogą używać. Nie ma powodu, dla którego osoba bez wiedzy o tym, czym jest muteks lub co robi, nie powinna być w stanie wykorzystać wszystkiego, co ma, zarówno pod względem umiejętności, jak i zasobów. Obiekt funkcjonuje jak obiekt, ale wszędzie tam, gdzie w innym przypadku zderzałyby się dwa konteksty, pthreads zapewnia stabilność i bezpieczeństwo.

Każdy, kto pracował w Javie, zobaczy podobieństwa między obiektem pthreads i wątkami w Javie, ci sami ludzie bez wątpienia zobaczą błąd o nazwie ConcurrentModificationException - jak to brzmi jako błąd wywoływany przez środowisko wykonawcze Java, jeśli dwa wątki zapisują te same dane fizyczne jednocześnie. Rozumiem, dlaczego istnieje, ale zaskakuje mnie to, że przy tak tanich zasobach, w połączeniu z faktem, że środowisko wykonawcze jest w stanie wykryć współbieżność w dokładnym i jedynym czasie, w którym można osiągnąć bezpieczeństwo dla użytkownika, który zdecyduje zgłosić prawdopodobnie krytyczny błąd w czasie wykonywania, zamiast zarządzać wykonywaniem i dostępem do danych.

Żadne takie głupie błędy nie będą emitowane przez pthreads, uważam, że API zostało napisane tak, aby wątki były tak stabilne i kompatybilne, jak to tylko możliwe.

Wielowątkowość nie jest podobna do korzystania z nowej bazy danych, należy zwrócić szczególną uwagę na każde słowo w podręczniku i przykłady dostarczane z pthreads.

Na koniec z podręcznika PHP:

pthreads był i jest eksperymentem z całkiem dobrymi wynikami. Wszelkie ograniczenia lub funkcje mogą ulec zmianie w dowolnym momencie; taka jest natura eksperymentowania. Jej ograniczenia - często narzucane przez implementację - istnieją nie bez powodu; celem pthreads jest dostarczenie użytecznego rozwiązania do wielozadaniowości w PHP na każdym poziomie. W środowisku, w którym działa pthreads, konieczne są pewne ograniczenia i ograniczenia, aby zapewnić stabilne środowisko.

Joe Watkins
źródło
14
Kompletny nonsens.
Joe Watkins
7
@GeoC. Nie jestem nawet pewien, o co ci chodzi, to tylko mnóstwo bełkotu i nie podajesz żadnych logicznych ani innych powodów , dla których nie zgadzasz się z żadnymi argumentami (których tak naprawdę nie widzę w poście) .
Jimbo,
13
@Tudor Nie sądzę, że naprawdę wiesz, o czym mówisz, więc cieszę się, że cię zignoruję.
Joe Watkins
4
@Tudor - wielu naukowców nie „widziało sensu” czegoś nowego w swojej branży lub czegoś pożytecznego. Historia pokazała, że ​​najczęściej ludzie tacy jak ty są po prostu w błędzie, to fakt. Tak jak faktem jest, że wszystko, co tu napisałeś, bez lepszego słowa, jest odchodami. Zdecydowanie radzę, mając na uwadze wszystko, co pozytywne, nie brać udziału w tematach, o których nic nie wiesz (to jest jeden).
NB
12
Zabawna rzecz. Joe Watkins jest autorem pthreads, a Tudor wciąż próbuje udowodnić mu, że się mylił.
Hristo Valkanov,
49

Oto przykład tego, co zasugerował Wilco:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);

Zasadniczo powoduje to wykonanie skryptu PHP w wierszu poleceń, ale natychmiast zwraca PID, a następnie działa w tle. (Echo $! Zapewnia, że ​​nie jest zwracane nic innego niż PID.) Pozwala to na kontynuowanie lub zakończenie skryptu PHP, jeśli chcesz. Kiedy z tego skorzystałem, przekierowałem użytkownika na inną stronę, gdzie co 5 do 60 sekund wywoływane jest połączenie AJAX w celu sprawdzenia, czy raport nadal działa. (Mam tabelę do przechowywania identyfikatora gen_id i użytkownika, z którym jest powiązany). Skrypt sprawdzający uruchamia następujące czynności:

exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
     // less than 2 rows in the ps, therefore report is complete
}

Tutaj znajduje się krótki post na temat tej techniki: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Darryl Hein
źródło
Mam mały problem, jak sprawdzić stan procesu w tle? Czy możesz mnie oświecić
slier
25

W skrócie: tak, w php jest wielowątkowość, ale zamiast tego powinieneś użyć wielowątkowości.

Informacje backgroud: wątki a procesy

Zawsze jest trochę niejasności co do rozróżnienia wątków i procesów, więc krótko opiszę oba:

  • Gwint to sekwencja rozkazów, które przetwarzają CPU. Jedyne dane, z których się składa, to licznik programu. Każdy rdzeń procesora będzie przetwarzał tylko jeden wątek na raz, ale może przełączać się między wykonywaniem różnych za pomocą harmonogramu.
  • Proces jest zbiorem wspólnych zasobów. Oznacza to, że składa się z części pamięci, zmiennych, instancji obiektów, uchwytów plików, muteksów, połączeń z bazami danych i tak dalej. Każdy proces zawiera również jeden lub więcej wątków. Wszystkie wątki tego samego procesu współużytkują jego zasoby, więc możesz użyć zmiennej w jednym wątku, który utworzyłeś w innym. Jeśli te wątki są częściami dwóch różnych procesów, nie mogą uzyskać bezpośredniego dostępu do swoich zasobów. W takim przypadku potrzebujesz komunikacji między procesami poprzez np. Potoki, pliki, gniazda ...

Wieloprocesowość

Możesz osiągnąć obliczenia równoległe, tworząc nowe procesy (które zawierają również nowy wątek) za pomocą php. Jeśli Twoje wątki nie potrzebują dużo komunikacji lub synchronizacji, to Twój wybór, ponieważ procesy są izolowane i nie mogą kolidować ze sobą w pracy. Nawet jeśli jeden się wywali, to nie dotyczy innych. Jeśli potrzebujesz dużo komunikacji, powinieneś czytać dalej na temat „wielowątkowości” lub - niestety - rozważyć użycie innego języka programowania, ponieważ komunikacja między procesami i synchronizacja wprowadzają wiele komplikacji.

W php masz dwa sposoby na utworzenie nowego procesu:

niech system operacyjny zrobi to za Ciebie : możesz powiedzieć swojemu systemowi operacyjnemu, aby utworzył nowy proces i uruchomił w nim nowy (lub ten sam) skrypt php.

  • w przypadku Linuksa możesz użyć następującego lub rozważyć odpowiedź Darryla Heina :

    $cmd = 'nice php script.php 2>&1 & echo $!';
    pclose(popen($cmd, 'r'));
    
  • w przypadku okien możesz użyć tego:

    $cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
    pclose(popen($cmd, 'r'));
    

zrób to sam za pomocą rozwidlenia : php zapewnia również możliwość użycia rozwidlenia za pomocą funkcji pcntl_fork () . Dobry poradnik, jak to zrobić, można znaleźć tutaj, ale zdecydowanie odradzam go używać, ponieważ widelec jest zbrodnią przeciwko ludzkości, a zwłaszcza przeciwko oop.

Wielowątkowość

Dzięki wielowątkowości wszystkie Twoje wątki udostępniają swoje zasoby, dzięki czemu możesz łatwo komunikować się i synchronizować je bez dużego narzutu. Z drugiej strony musisz wiedzieć, co robisz, ponieważ warunki wyścigu i zakleszczenia są łatwe do wytworzenia, ale bardzo trudne do debugowania.

Standardowy php nie zapewnia wielowątkowości, ale istnieje (eksperymentalne) rozszerzenie, które faktycznie to robi - pthreads . Jego dokumentacja API trafiła nawet do php.net . Dzięki niemu możesz zrobić coś, co możesz w prawdziwych językach programowania :-) w ten sposób:

class MyThread extends Thread {
    public function run(){
        //do something time consuming
    }
}

$t = new MyThread();
if($t->start()){
    while($t->isRunning()){
        echo ".";
        usleep(100);
    }
    $t->join();
}

W przypadku Linuksa przewodnik instalacji znajduje się tutaj, w witrynie Stackoverflow.

W przypadku okien jest teraz jeden:

  • Najpierw potrzebujesz bezpiecznej wątkowo wersji php.
  • Potrzebujesz wstępnie skompilowanych wersji obu pthreads i jego rozszerzenia php. Można je pobrać tutaj . Upewnij się, że pobierasz wersję zgodną z Twoją wersją php.
  • Skopiuj plik php_pthreads.dll (z właśnie pobranego pliku ZIP) do folderu rozszerzenia php ([katalog php] / ext).
  • Skopiuj plik pthreadVC2.dll do [phpDirectory] (folder główny - nie folder rozszerzenia).
  • Edytuj [phpDirectory] /php.ini i wstaw następujący wiersz

    extension=php_pthreads.dll
    
  • Przetestuj to za pomocą powyższego skryptu z odrobiną snu lub czymś tam, gdzie jest komentarz.

A teraz duże, ALE : Chociaż to naprawdę działa, php pierwotnie nie był przeznaczony do wielowątkowości. Istnieje wersja php bezpieczna wątkowo i od wersji 5.4 wydaje się być prawie wolna od błędów, ale używanie php w środowisku wielowątkowym jest nadal odradzane w podręczniku php (ale może po prostu nie zaktualizowali podręcznika na to jeszcze). Dużo większym problemem może być to, że wiele popularnych rozszerzeń nie jest bezpiecznych dla wątków . Możesz więc otrzymywać wątki z tym rozszerzeniem php, ale funkcje, na których polegasz, nadal nie są bezpieczne dla wątków, więc prawdopodobnie napotkasz warunki wyścigu, zakleszczenia i tak dalej w kodzie, którego sam nie napisałeś ...

Francois Bourgeois
źródło
5
To strasznie źle, artykuł, do którego się odnosiliście pochodzi z 2008 roku. Gdyby PHP nie był w rdzeniu bezpieczny wątkowo, nie miałby wątkowych modułów SAPI.
Joe Watkins
1
@Joe: W porządku, zmieniłem to w rdzeniu, jest bezpieczny dla wątków, ale wiele rozszerzeń nie.
Francois Bourgeois
1
Dużo ? Myślę, że okaże się, że jest ich bardzo mało, znalazłeś dokumentację, ale nie przeczytałeś jej poprawnie: Uwaga: te oznaczone * nie są bibliotekami bezpiecznymi wątkowo i nie powinny być używane z PHP jako modułem serwera w multi -wątkowe serwery internetowe Windows (IIS, Netscape). Nie ma to jeszcze znaczenia w środowiskach Unix.
Joe Watkins,
6
PHP jest bardzo bezpieczny dla wątków i od wielu lat niektóre biblioteki zewnętrzne i kilka dołączonych nie są, ale jest dobrze udokumentowany i tak czy inaczej dość oczywisty. pthreads tworzy wątki, które są tak samo bezpieczne, jak wątki tworzone przez zend w wielowątkowym sapi, wiem o tym, bo sam pisałem pthreads. Używa każdego dostępnego API udostępnionego przez PHP, tak jak API serwera, nie mówię, że jest całkowicie stabilny, ale namalowany obraz jest po prostu błędny i bardzo słabo poinformowany.
Joe Watkins,
@Joe: Kiedy podręcznik mówi, że nie ma to znaczenia dla środowisk Unix, odnoszą się do faktu, że w systemie Unix apache używa wielu procesów, a Windows używa wątków. Mówią więc, że „jeśli i tak nie używasz wątków, nie musisz się martwić o rozszerzenia, które nie są bezpieczne dla wątków”. Kiedy używamy wątków z pthreads, ma to oczywiście znaczenie również w środowiskach Unix.
Francois Bourgeois
17

Możesz użyć pcntl_fork (), aby osiągnąć coś podobnego do wątków. Technicznie są to oddzielne procesy, więc komunikacja między nimi nie jest tak prosta w przypadku wątków i uważam, że nie zadziała, jeśli PHP zostanie wywołane przez apache.

davr
źródło
4
Z powodzeniem używam pcntl_fork do zrównoleglenia dość ogromnego zadania importu danych. Działa świetnie i miałem go w około godzinę. Jest trochę krzywej uczenia się, ale kiedy już zrozumiesz, co się dzieje, jest to całkiem proste.
Frank Farmer
Frank, czy to z php CLI czy PHP z apache?
Artem Russakovskii
@Artem: Też chciałbym wiedzieć.
Josh K
5
@Frank Farmer dokucza nam ... tak jak pakiet PECL.
Roger,
1
Używałem pcntl_fork z CLI. Nigdy nie próbowałem tego w Apache; to brzmi ryzykownie. Nawet w CLI wystąpiły nieoczekiwane problemy. Wydawało mi się, że mam problem polegający na tym, że jeśli jedno dziecko zamyka uchwyt bazy danych (ponieważ zakończyło swoją pracę), zamykało również połączenie dla rodzeństwa. Ponieważ dzieci są kopiami rodzica, przygotuj się na dziwactwa. Od tego czasu przeprojektowałem swój kod, aby po prostu tworzyć nowe, całkowicie oddzielne procesy za pośrednictwem exec () - w ten sposób jest czystszy.
Frank Farmer
7

pcntl_fork()jest tym, czego szukasz, ale jego proces rozwidla się, a nie wątkuje. więc będziesz miał problem z wymianą danych. aby je rozwiązać, możesz użyć funkcji semafora phps ( http://www.php.net/manual/de/ref.sem.php ), kolejki wiadomości mogą być na początku trochę łatwiejsze niż segmenty pamięci współdzielonej.

W każdym razie strategia, której używam w ramach sieci Web, którą tworzę, która ładuje bloki strony internetowej wymagające dużej ilości zasobów (prawdopodobnie z żądaniami zewnętrznymi) równolegle: robię kolejkę zadań, aby wiedzieć, na jakie dane czekam, a następnie rozwidlam z zadań dla każdego procesu. po zakończeniu przechowują swoje dane w pamięci podręcznej apc pod unikalnym kluczem, do którego ma dostęp proces nadrzędny. gdy wszystkie dane są dostępne, trwa dalej. używam prostego usleep()czekania, ponieważ komunikacja między procesami nie jest możliwa w apache (dzieci tracą połączenie z rodzicami i stają się zombie ...). więc to prowadzi mnie do ostatniej rzeczy: ważne jest, aby zabić każde dziecko! są też klasy, które rozwidlają procesy, ale przechowują dane, nie badałem ich, ale zend framework je ma i zwykle wykonują wolny, ale niezawodny kod. można go znaleźć tutaj: http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html myślę, że używają segmentów shm! no wreszcie, na tej stronie zend jest błąd, drobny błąd w przykładzie.

while ($process1->isRunning() && $process2->isRunning()) {
    sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
    sleep(1);
}
Surrican
źródło
5

Mam klasę wątków PHP, która działa bezbłędnie w środowisku produkcyjnym od ponad dwóch lat.

EDYCJA: jest teraz dostępna jako biblioteka kompozytora i jako część mojego frameworka MVC, Hazaar MVC.

Zobacz: https://git.hazaarlabs.com/hazaar/hazaar-thread

Jamie Carl
źródło
Co jeśli, idąc za twoim przykładem, program w file.php, powiedzmy na przykład, potwierdzi istnienie listy adresów uris witryny 10k, a następnie musi zapisać wynik w pliku CSV ... Czy ten zapisany plik byłby problem?
Roger,
Proces podrzędny będzie działał jako ten sam użytkownik, co serwer WWW / skrypt nadrzędny. Tak więc podczas pisania plików będziesz mieć te same uwagi dotyczące uprawnień, jak zwykle. Jeśli masz problemy z zapisywaniem plików, spróbuj zapisać do / tmp, a kiedy to zadziała, przejdź stamtąd.
Jamie Carl
1
Link jest teraz martwy z powodu przeprojektowania, możesz go pobrać w drodze powrotnej tutaj: web.archive.org/web/20130922043615/http://dev.funkynerd.com/ ...
Tony
Dodano do mojego frameworka MVC teraz. Zobacz: git.hazaarlabs.com/hazaar/hazaar-thread
Jamie Carl
1

Słyszałeś kiedyś o appservertechdivision?

Jest napisany w PHP i działa jako serwer aplikacji zarządzający wielowątkowością dla aplikacji php o dużym ruchu. Nadal jest w fazie beta, ale obiecuje.

user2627170
źródło
-3

Istnieje raczej mało znana i wkrótce wycofana funkcja zwana tickami . Jedyne, do czego go kiedykolwiek używałem, to pozwolić skryptowi przechwycić SIGKILL (Ctrl + C) i zamknąć go z wdziękiem.

troelskn
źródło
3
Kleszcze nie są wykonywane równolegle. Zasadniczo po każdej instrukcji uruchamiana jest funkcja tick. Gdy działa funkcja tick, główny kod nie działa.
Frank Farmer
1
ticky są potrzebne tylko dla obsługi signal ().
Nick