programing

PHP에는 스레드 기능이 있습니까?

newsource 2022. 9. 19. 23:44

PHP에는 스레드 기능이 있습니까?

스레드라는 PCL 패키지를 찾았는데 아직 출시되지 않았습니다.그리고 PHP 웹사이트에는 아무것도 뜨지 않습니다.

pthreads 확장에 대한 PHP 매뉴얼에서 다음을 참조하십시오.

pthreads는 PHP에서 사용자 랜드 멀티스레딩을 허용하는 객체 지향 API입니다.여기에는 웹 또는 콘솔을 대상으로 하는 멀티 스레드 응용 프로그램을 만드는 데 필요한 모든 도구가 포함되어 있습니다.PHP 애플리케이션은 스레드, 워커 및 스태커블을 생성, 읽기, 쓰기, 실행 및 동기화할 수 있습니다.

믿기 힘들겠지만, 그건 완전히 사실이야.현재 PHP는 멀티스레드를 원하는 사용자를 위해 사용할 수 있습니다.

PHP4의 첫 번째 릴리스인 2000년 5월 22일, PHP는 스레드 세이프 아키텍처와 함께 출하되었습니다.이것은 멀티 스레드 SAPI(Server API) 환경에서 인터프리터의 여러 인스턴스를 별도의 스레드로 실행하는 방법입니다.지난 13년간 이 아키텍처의 설계는 다음과 같이 유지되고 발전되어 왔습니다.그것은 그 이후로 세계에서 가장 큰 웹사이트에서 실전 가동되고 있다.

사용자 랜드에서의 스레드화는 PHP 팀에게 전혀 문제가 되지 않았으며, 오늘날에도 마찬가지입니다.PHP가 업무를 수행하는 세계에는 이미 정의된 확장 방법이 있다는 것을 이해해야 합니다.수년간 PHP가 존재하면서 하드웨어는 점점 더 저렴해졌기 때문에 PHP 팀의 관심사는 점점 줄어들었습니다.가격은 저렴해졌지만, 한층 더 강력해졌습니다.오늘날, 델의 휴대 전화와 태블릿은 듀얼 코어 아키텍처와 쿼드 코어 아키텍처와 그에 부속되는 RAM이 풍부합니다.데스크탑과 서버는 일반적으로 8 또는 16기가바이트의 RAM을 탑재하고 있습니다.단, 예산 범위 내에서 2대의 데스크톱은 거의 사용되지 않습니다.우리 대부분은 ul.

또한 PHP는 프로그래머가 아닌 사람들을 위해 작성되었으며, 많은 취미 생활자들이 모국어로 사용하고 있습니다.PHP가 이처럼 쉽게 채택되는 이유는 PHP가 배우고 쓰기 쉬운 언어이기 때문입니다.오늘날 PHP가 이처럼 신뢰할 수 있는 이유는 PHP의 설계에 들어가는 방대한 양의 작업과 PHP 그룹의 모든 결정 때문입니다.오랜 세월이 흘렀지만 신뢰성과 순전한 위대함 때문에 경쟁사들은 시간이나 압박에 시달리고 있습니다.

멀티 스레드 프로그래밍은 대부분의 경우 쉽지 않습니다. 가장 일관성 있고 신뢰할 수 있는 API를 사용하더라도 생각해야 할 것들이 있고 많은 오해들이 있습니다.PHP 그룹은 사용자 랜드 멀티스레딩이 핵심 기능이 되는 것을 원하지 않으며, 이는 결코 심각한 관심을 받은 적이 없으며, 당연히 그렇습니다.PHP는 모든 사람에게 복잡하지 않아야 합니다.

모든 것을 고려해 볼 때, PHP가 생산 준비 및 테스트된 기능을 활용할 수 있도록 함으로써 얻을 수 있는 이점이 있습니다. 더 많은 작업을 추가할 수 있는 방법이 항상 필요한 것은 아닙니다.

pthreads는 사용자가 PHP 애플리케이션을 멀티스레드 할 수 있는 API를 제공합니다.이 API는 매우 진행 중인 작업으로 안정성과 완성도의 베타 레벨을 지정했습니다.

PHP가 사용하는 라이브러리 중 일부는 스레드 세이프가 아니라는 것은 상식입니다.프로그래머에게는 pthreads가 이를 변경할 수 없으며 시도하지 않는다는 것을 명확히 해야 합니다.단, 인터프리터의 다른 스레드세이프 설정과 마찬가지로 스레드세이프 라이브러리는 사용할 수 있습니다.

pthreads는 Posix Threads(Windows에서도)를 활용합니다.프로그래머가 작성하는 것은 실제 실행 스레드입니다만, 이러한 스레드가 유용하려면 , PHP 를 인식하고 있을 필요가 있습니다.이것은 사용자 코드를 실행하고 변수를 공유해, 편리한 통신 수단(동기화)을 가능하게 합니다.따라서 모든 스레드는 인터프리터의 인스턴스를 사용하여 작성되지만 멀티 스레드 서버 API 환경과 마찬가지로 인터프리터의 다른 모든 인스턴스와 분리되도록 설계되어 있습니다.pthreads는 건전하고 안전한 방법으로 갭을 메우려고 합니다.C 스레드 프로그래머가 우려하는 많은 부분은 pthreads 프로그래머에게는 해당되지 않습니다.설계상 pthreads는 읽기 시 복사되고 쓰기 시 복사됩니다(RAM은 저렴합니다). 따라서 동일한 물리 데이터를 조작하는 두 인스턴스는 없지만 두 인스턴스는 모두 다른 스레드 내의 데이터에 영향을 미칠 수 있습니다.PHP가 핵심 프로그래밍에서 스레드 안전하지 않은 기능을 사용할 수 있다는 사실은 전혀 관련이 없으며 사용자 스레드도 완벽하게 안전합니다.

Why copy on read and copy on write:

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

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

(1) While a read, and write lock are held on the pthreads object data store, data is copied from its original location in memory to the object store. pthreads does not adjust the refcount of the variable, Zend is able to free the original data if there are no further references to it.

(2) The argument to someOperation references the object store, the original data stored, which it itself a copy of the result of (1), is copied again for the engine into a zval container, while this occurs a read lock is held on the object store, the lock is released and the engine can execute the function. When the zval is created, it has a refcount of 0, enabling the engine to free the copy on completion of the operation, because no other references to it exist.

(3) The last argument to preg_match references the data store, a read lock is obtained, the data set in (1) is copied to a zval, again with a refcount of 0. The lock is released, The call to preg_match operates on a copy of data, that is itself a copy of the original data.

Things to know:

  • The object store's hash table where data is stored, thread safe, is
    based on the TsHashTable shipped with PHP, by Zend.

  • The object store has a read and write lock, an additional access lock is provided for the TsHashTable such that if requires ( and it does, var_dump/print_r, direct access to properties as the PHP engine wants to reference them ) pthreads can manipulate the TsHashTable outside of the defined API.

  • The locks are only held while the copying operations occur, when the copies have been made the locks are released, in a sensible order.

This means:

  • When a write occurs, not only are a read and write lock held, but an additional access lock. The table itself is locked down, there is no possible way another context can lock, read, write or affect it.

  • When a read occurs, not only is the read lock held, but the additional access lock too, again the table is locked down.

No two contexts can physically nor concurrently access the same data from the object store, but writes made in any context with a reference will affect the data read in any context with a reference.

이는 공유되지 않은 아키텍처이며 공존할 수 있는 유일한 방법입니다.조금 지식이 있는 사람은 그것을 알 것입니다.여기서는 많은 복사가 이루어지고 있습니다.그리고 그들은 그것이 좋은 것인지 궁금해 할 것입니다.동적 런타임 내에서 많은 복사가 이루어지는데, 이것이 동적 언어의 동적입니다.pthreads는 오브젝트 레벨에서 구현됩니다.이는 하나의 오브젝트에 대한 적절한 제어를 얻을 수 있기 때문입니다.그러나 메서드(프로그래머가 실행하는 코드)는 잠금과 복사가 없는 다른 컨텍스트(로컬 메서드 범위)를 가집니다.pthreads 객체의 경우 객체 스코프는 컨텍스트 간에 데이터를 공유하는 방법, 즉 그 목적으로 취급해야 합니다.따라서 로컬 스코프 변수를 스레드 객체의 다른 메서드에 전달하는 등 필요한 경우가 아니면 객체 스토어가 잠기지 않도록 하는 방법을 채택할 수 있습니다.예를 들어 실행 시 객체 스토어에서 복사하는 것이 아닙니다.

PHP에서 사용할 수 있는 라이브러리와 확장의 대부분은 서드파티와 관련된 씬 래퍼이며, PHP의 핵심 기능은 어느 정도 동일합니다.pthreads는 Posix Threads에 대한 얇은 래퍼가 아니라 Posix Threads에 기반한 스레드 API입니다.사용자가 이해하지 못하거나 사용할 수 없는 스레드를 PHP에 구현하는 것은 의미가 없습니다.뮤텍스가 무엇인지 전혀 알지 못하는 사람이 기술과 자원 면에서 그들이 가진 모든 것을 이용할 수 없을 이유는 없습니다.오브젝트는 오브젝트처럼 기능하지만 2개의 컨텍스트가 충돌할 경우 pthreads는 안정성과 안전성을 제공합니다.

자바에서 일해 본 사람이라면 pthreads 객체와 자바 스레드의 유사점을 알 수 있을 것입니다.이러한 사람들은 Concurrent Modification이라고 불리는 오류를 봤을 것입니다.예외 - 두 개의 스레드가 동일한 물리적 데이터를 동시에 쓰는 경우 Java 런타임에 의해 발생하는 오류가 발생합니다.왜 존재하는지는 이해하지만, 저렴한 리소스로 사용자의 안전을 확보할 수 있는 정확하고 유일한 시점에 동시성을 검출할 수 있다는 사실과 더불어 실행 시 실행 및 데이터 액세스를 관리하는 대신 실행 시 치명적인 오류를 발생시키는 것을 선택한다는 것은 이해할 수 없습니다.

pthreads에 의해 이러한 바보 같은 오류가 발생하지 않도록 API는 가능한 한 안정적이고 호환성이 있도록 작성되었다고 생각합니다.

멀티스레딩은 새로운 데이터베이스를 사용하는 것이 아니기 때문에 매뉴얼 내의 모든 단어와 pthread와 함께 제공되는 예제에 주의를 기울여야 합니다.

마지막으로, PHP 매뉴얼:

pthreads는 꽤 좋은 결과를 가진 실험이었고 지금도 그렇습니다.이러한 제한이나 특징은 언제든지 변경될 수 있습니다. 이것이 실험의 특성입니다.pthreads의 목적은 PHP에서의 멀티태스킹에 대한 사용 가능한 솔루션을 제공하는 것입니다.pthreads가 실행되는 환경에서는 안정된 환경을 제공하기 위해 몇 가지 제약사항과 제한이 필요합니다.

다음은 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);

기본적으로 명령줄에서 PHP 스크립트를 실행하지만 즉시 PID를 반환하고 백그라운드에서 실행됩니다.(에코 $!는 PID 이외에는 반환되지 않습니다).이것에 의해, 필요에 따라서 PHP 스크립트를 속행하거나 종료하거나 할 수 있습니다.이것을 사용하면, 유저를 다른 페이지로 리다이렉트 해, 리포트가 아직 동작하고 있는지를 확인하기 위해서, 5 ~60초마다 AJAX 콜이 발신됩니다.(gen_id와 관련된 사용자를 저장할 테이블이 있습니다.)검사 스크립트는 다음을 수행합니다.

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

이 기술에 대한 짧은 글은 http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/에 게재되어 있습니다.

제가 아는 건 없어요.다음으로 가장 좋은 방법은 CLI를 통해 다른 스크립트를 실행하는 것입니다만, 이것은 조금 초보적인 것입니다.수행하려는 작업 및 복잡도에 따라 옵션이 될 수도 있고 아닐 수도 있습니다.

요컨대: 네, php에는 멀티스레딩이 있지만 대신 멀티프로세싱을 사용해야 합니다.

배경 정보: 스레드와 프로세스

스레드와 프로세스의 구별에 대해서는 항상 약간 혼란이 있기 때문에 두 가지를 간략하게 설명하겠습니다.

  • 스레드는 CPU가 처리하는 일련의 명령어입니다.이 데이터는 프로그램 카운터로만 구성됩니다.각 CPU 코어는 한 번에 하나의 스레드만 처리하지만 스케줄링을 통해 다른 스레드 실행 간에 전환할 수 있습니다.
  • 프로세스는 공유 리소스 집합입니다.즉, 메모리, 변수, 객체 인스턴스, 파일 핸들, 뮤텍스, 데이터베이스 연결 등으로 구성됩니다.각 프로세스에는 하나 이상의 스레드도 포함됩니다.동일한 프로세스의 모든 스레드는 리소스를 공유하므로 다른 스레드에서 생성한 변수를 사용할 수 있습니다.이러한 스레드가 서로 다른 두 프로세스의 일부인 경우 서로 리소스에 직접 액세스할 수 없습니다.이 경우 파이프, 파일, 소켓 등을 통한 프로세스통신이 필요합니다.

멀티프로세서

php를 사용하여 새로운 프로세스(새로운 스레드도 포함)를 작성함으로써 병렬 컴퓨팅을 실현할 수 있습니다.스레드에 많은 통신이나 동기화가 필요하지 않은 경우 프로세스가 격리되어 있어 서로의 작업을 방해할 수 없기 때문에 이는 사용자의 선택입니다.한 명이 추락해도 다른 사람은 상관없다.많은 커뮤니케이션이 필요한 경우는, 「멀티스레딩」으로 읽거나, 다른 프로그래밍 언어를 사용하는 것을 검토해 주세요.프로세스간의 통신과 동기화에 의해서 많은 안색이 생기기 때문입니다.

php에서는 새로운 프로세스를 작성하기 위한 두 가지 방법이 있습니다.

OS가 대신하도록 합니다.운영체제에 새로운 프로세스를 생성하여 새로운 (또는 동일한) php 스크립트를 실행하도록 지시할 수 있습니다.

  • Linux 의 경우는, 다음의 항목을 사용하거나, Darryl Hein 의 회답을 고려해 주세요.

    $cmd = 'nice php script.php 2>&1 & echo $!';
    pclose(popen($cmd, 'r'));
    
  • Windows 의 경우는, 다음을 사용할 수 있습니다.

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

포크로 직접 실행: php는 pcntl_forking 함수를 통해 포킹을 사용할 수도 있습니다.이 방법에 대한 좋은 튜토리얼은 여기에서 찾을 수 있지만 포크는 반인륜적 범죄이며 특히 oop에 반하는 범죄이기 때문에 사용하지 않는 것이 좋습니다.

멀티스레딩

멀티스레딩을 사용하면 모든 스레드가 리소스를 공유하므로 많은 오버헤드 없이 쉽게 서로 통신하고 동기화할 수 있습니다.다른 한편에서는 레이스 조건과 데드록은 생성은 쉽지만 디버깅은 매우 어렵기 때문에 무엇을 하고 있는지 알아야 합니다.

표준 php는 멀티스레딩을 제공하지 않지만 실제로 제공하는 (실험적인) 확장이 있습니다 - pthreads.api 문서에서는 php.net에 들어가기도 했습니다.이 기능을 사용하면 실제 프로그래밍 언어로 다음과 같은 작업을 수행할 수 있습니다.

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();
}

For linux there is an installation guide right here at stackoverflow's.

For windows there is one now:

  • First you need the thread-safe version of php.
  • You need the pre-compiled versions of both pthreads and its php extension. They can be downloaded here. Make sure that you download the version that is compatible with your php version.
  • Copy php_pthreads.dll (from the zip you just downloaded) into your php extension folder ([phpDirectory]/ext).
  • Copy pthreadVC2.dll into [phpDirectory] (the root folder - not the extension folder).
  • Edit [phpDirectory]/php.ini and insert the following line

    extension=php_pthreads.dll
    
  • Test it with the script above with some sleep or something right there where the comment is.

And now the big BUT: Although this really works, php wasn't originally made for multithreading. There exists a thread-safe version of php and as of v5.4 it seems to be nearly bug-free but using php in a multi-threaded environment is still discouraged in the php manual (but maybe they just did not update their manual on this, yet). A much bigger problem might be that a lot of common extensions are not thread-safe. So you might get threads with this php extension but the functions you're depending on are still not thread-safe so you will probably encounter race conditions, deadlocks and so on in code you did not write yourself...

You can use pcntl_fork() to achieve something similar to threads. Technically it's separate processes, so the communication between the two is not as simple with threads, and I believe it will not work if PHP is called by apache.

If anyone cares, I have revived php_threading (not the same as threads, but similar) and I actually have it to the point where it works (somewhat) well!

Project page

Download (for Windows PHP 5.3 VC9 TS)

Examples

README

pcntl_fork() is what you are searching for, but its process forking not threading. so you will have the problem of data exchange. to solve them you can use phps semaphore functions ( http://www.php.net/manual/de/ref.sem.php ) message queues may be a bit easier for the beginning than shared memory segments.

Anyways, a strategy i am using in a web framework that i am developing which loads resource intensive blocks of a web page (probably with external requests) parallel: i am doing a job queue to know what data i am waiting for and then i fork off the jobs for every process. once done they store their data in the apc cache under a unique key the parent process can access. once every data is there it continues. i am using simple usleep() to wait because inter process communication is not possible in apache (children will loose the connection to their parents and become zombies...). so this brings me to the last thing: its important to self kill every child! there are as well classes that fork processes but keep data, i didn't examine them but zend framework has one, and they usually do slow but reliably code. you can find it here: http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html i think they use shm segments! well last but not least there is an error on this zend website, minor mistake in the example.

while ($process1->isRunning() && $process2->isRunning()) {
    sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
    sleep(1);
}

There is a Threading extension being activley developed based on PThreads that looks very promising at https://github.com/krakjoe/pthreads

Just an update, its seem that PHP guys are working on supporting thread and its available now.

Here is the link to it: http://php.net/manual/en/book.pthreads.php

I have a PHP threading class that's been running flawlessly in a production environment for over two years now.

EDIT: This is now available as a composer library and as part of my MVC framework, Hazaar MVC.

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

I know this is a way old question, but you could look at http://phpthreadlib.sourceforge.net/

Bi-directional communication, support for Win32, and no extensions required.

Ever heard about appserver from techdivision?

It is written in php and works as a appserver managing multithreads for high traffic php applications. Is still in beta but very promesing.

There is the rather obscure, and soon to be deprecated, feature called ticks. The only thing I have ever used it for, is to allow a script to capture SIGKILL (Ctrl+C) and close down gracefully.

ReferenceURL : https://stackoverflow.com/questions/209774/does-php-have-threading