PHP에는 스레딩이 있습니까?
이 PECL 패키지가 threads라는 것을 발견 했지만 아직 릴리스가 없습니다. 그리고 PHP 웹 사이트에는 아무것도 나오지 않습니다.
내가 아는 것이 없습니다. 다음으로 가장 좋은 방법은 CLI를 통해 한 스크립트가 다른 스크립트를 실행하도록하는 것이지만 약간 기초적인 내용입니다. 당신이하려는 일과 그것이 얼마나 복잡한 지에 따라, 이것은 옵션 일 수도 있고 아닐 수도 있습니다.
pthreads 확장에 대한 PHP 매뉴얼에서 :
pthreads는 PHP에서 사용자 랜드 멀티 스레딩을 허용하는 객체 지향 API입니다. 웹 또는 콘솔을 대상으로하는 멀티 스레드 응용 프로그램을 만드는 데 필요한 모든 도구가 포함되어 있습니다. PHP 애플리케이션은 스레드, 워커 및 스택 어블을 생성, 읽기, 쓰기, 실행 및 동기화 할 수 있습니다.
이것이 들리는 것처럼, 그것은 사실입니다. 오늘날, PHP는 그것을 시도하려는 사람들을 위해 멀티 스레드를 할 수 있습니다.
PHP4의 첫 번째 릴리스 인 2000 년 5 월 22 일, PHP는 스레드 안전 아키텍처와 함께 제공되어 다중 스레드 SAPI (서버 API) 환경에서 별도의 스레드로 여러 인터프리터의 인터프리터 인스턴스를 실행할 수있는 방법입니다. 지난 13 년 동안이 아키텍처의 디자인은 유지되고 발전되었습니다. 그 이후로 세계에서 가장 큰 웹 사이트에서 프로덕션으로 사용되었습니다.
사용자 영역에서의 스레딩은 PHP 팀에게는 전혀 관심이 없었으며 오늘날에도 마찬가지입니다. PHP가 비즈니스를 수행하는 세계에는 이미 하드웨어 확장이라는 정의 된 확장 방법이 있다는 것을 이해해야합니다. 수년 동안 PHP가 존재하고 하드웨어는 저렴하고 저렴 해졌으며 이는 PHP 팀의 관심사가 점점 줄어 들었습니다. 저렴 해지면서 훨씬 강력 해졌습니다. 오늘날 우리의 휴대 전화 및 태블릿에는 듀얼 및 쿼드 코어 아키텍처와 많은 RAM이 있으며, 데스크탑 및 서버에는 일반적으로 8 또는 16 코어, 16 및 32 기가 바이트 RAM이 있지만 항상 2 개를 가질 수는 없습니다. 예산 내에서 두 대의 데스크톱을 사용하는 것이 우리에게는 거의 유용하지 않습니다.
또한 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은 저렴합니다), 따라서 두 인스턴스가 동일한 물리적 데이터를 조작하지 않습니다. 하지만 다른 스레드의 데이터에 영향을 줄 수 있습니다.
읽기에서 복사하고 쓰기에서 복사하는 이유 :
public function run() {
...
(1) $this->data = $data;
...
(2) $this->other = someOperation($this->data);
...
}
(3) echo preg_match($pattern, $replace, $thread->data);
(1) pthreads 객체 데이터 저장소에서 읽기 및 쓰기 잠금이 유지되는 동안 데이터는 메모리의 원래 위치에서 객체 저장소로 복사됩니다. pthreads는 변수의 참조 횟수를 조정하지 않으므로 Zend는 더 이상 참조가 없으면 원래 데이터를 해제 할 수 있습니다.
(2) someOperation에 대한 인수는 (1) 결과의 사본 자체가 엔진에 대해 zval 컨테이너로 다시 복사되는 저장된 원래 데이터 인 오브젝트 저장소를 참조합니다.이 경우 읽기 잠금이 유지됩니다. 오브젝트 저장소, 잠금이 해제되고 엔진이 기능을 실행할 수 있습니다. zval이 작성되면 참조 횟수는 0이며, 참조가 존재하지 않기 때문에 엔진이 조작 완료시 사본을 해제 할 수 있습니다.
(3) preg_match의 마지막 인수는 데이터 저장소를 참조하고, 읽기 잠금이 획득되고, (1)에 설정된 데이터가 다시 0의 참조 횟수로 zval에 복사됩니다. 잠금이 해제되고 preg_match에 대한 호출은 다음에서 작동합니다. 데이터 사본, 즉 그 자체가 원본 데이터의 사본.
알아야 할 사항 :
스레드 안전 데이터가 저장되는 객체 저장소의 해시 테이블은
Zend가 PHP와 함께 제공 한 TsHashTable을 기반으로합니다.오브젝트 저장소에는 읽기 및 쓰기 잠금이 있으며, TsHashTable에 대한 추가 액세스 잠금이 제공되므로 필요한 경우 (var_dump / print_r, PHP 엔진이 참조하고자하는 속성에 직접 액세스) pthread가 TsHashTable을 조작 할 수 있습니다. 정의 된 API 외부.
잠금은 복사 작업이 수행되는 동안, 사본이 만들어 졌을 때 잠금이 해제 된 상태에서 합리적인 순서로만 유지됩니다.
이것은 다음을 의미합니다.
쓰기가 발생하면 읽기 및 쓰기 잠금뿐만 아니라 추가 액세스 잠금이 유지됩니다. 테이블 자체가 잠겨 있으므로 다른 컨텍스트가 잠금, 읽기, 쓰기 또는 영향을 줄 수있는 방법이 없습니다.
읽기가 발생하면 읽기 잠금이 유지 될뿐만 아니라 추가 액세스 잠금도 다시 테이블이 잠 깁니다.
두 컨텍스트가 오브젝트 저장소에서 동일한 데이터에 물리적으로 또는 동시에 액세스 할 수는 없지만 참조를 사용하여 컨텍스트에서 작성된 쓰기는 참조가있는 컨텍스트에서 읽은 데이터에 영향을줍니다.
This is shared nothing architecture and the only way to exist is co-exist. Those a bit savvy will see that, there's a lot of copying going on here, and they will wonder if that is a good thing. Quite a lot of copying goes on within a dynamic runtime, that's the dynamics of a dynamic language. pthreads is implemented at the level of the object, because good control can be gained over one object, but methods - the code the programmer executes - have another context, free of locking and copies - the local method scope. The object scope in the case of a pthreads object should be treated as a way to share data among contexts, that is it's purpose. With this in mind you can adopt techniques to avoid locking the object store unless it's necessary, such as passing local scope variables to other methods in a threaded object rather than having them copy from the object store upon execution.
Most of the libraries and extensions available for PHP are thin wrappers around 3rd parties, PHP core functionality to a degree is the same thing. pthreads is not a thin wrapper around Posix Threads; it is a threading API based on Posix Threads. There is no point in implementing Threads in PHP that it's users do not understand or cannot use. There's no reason that a person with no knowledge of what a mutex is or does should not be able to take advantage of all that they have, both in terms of skill, and resources. An object functions like an object, but wherever two contexts would otherwise collide, pthreads provides stability and safety.
Anyone who has worked in java will see the similarities between a pthreads object and threading in java, those same people will have no doubt seen an error called ConcurrentModificationException - as it sounds an error raised by the java runtime if two threads write the same physical data concurrently. I understand why it exists, but it baffles me that with resources as cheap as they are, coupled with the fact the runtime is able to detect the concurrency at the exact and only time that safety could be achieved for the user, that it chooses to throw a possibly fatal error at runtime rather than manage the execution and access to the data.
No such stupid errors will be emitted by pthreads, the API is written to make threading as stable, and compatible as is possible, I believe.
Multi-threading isn't like using a new database, close attention should be paid to every word in the manual and examples shipped with pthreads.
Lastly, from the PHP manual:
pthreads was, and is, an experiment with pretty good results. Any of its limitations or features may change at any time; that is the nature of experimentation. It's limitations - often imposed by the implementation - exist for good reason; the aim of pthreads is to provide a useable solution to multi-tasking in PHP at any level. In the environment which pthreads executes, some restrictions and limitations are necessary in order to provide a stable environment.
Here is an example of what Wilco suggested:
$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);
Basically this executes the PHP script at the command line, but immediately returns the PID and then runs in the background. (The echo $! ensures nothing else is returned other than the PID.) This allows your PHP script to continue or quit if you want. When I have used this, I have redirected the user to another page, where every 5 to 60 seconds an AJAX call is made to check if the report is still running. (I have a table to store the gen_id and the user it's related to.) The check script runs the following:
exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
// less than 2 rows in the ps, therefore report is complete
}
There is a short post on this technique here: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
In short: yes, there is multithreading in php but you should use multiprocessing instead.
Backgroud info: threads vs. processes
There is always a bit confusion about the distinction of threads and processes, so i'll shortly describe both:
- A thread is a sequence of commands that the CPU will process. The only data it consists of is a program counter. Each CPU core will only process one thread at a time but can switch between the execution of different ones via scheduling.
- A process is a set of shared resources. That means it consists of a part of memory, variables, object instances, file handles, mutexes, database connections and so on. Each process also contains one or more threads. All threads of the same process share its resources, so you may use a variable in one thread that you created in another. If those threads are parts of two different processes, then they cannot access each others resources directly. In this case you need inter-process communication through e.g. pipes, files, sockets...
Multiprocessing
You can achieve parallel computing by creating new processes (that also contain a new thread) with php. If your threads do not need much communication or synchronization, this is your choice, since the processes are isolated and cannot interfere with each other's work. Even if one crashes, that doesn't concern the others. If you do need much communication, you should read on at "multithreading" or - sadly - consider using another programming language, because inter-process communication and synchronization introduces a lot of complexion.
In php you have two ways to create a new process:
let the OS do it for you: you can tell your operation system to create a new process and run a new (or the same) php script in it.
for linux you can use the following or consider Darryl Hein's answer:
$cmd = 'nice php script.php 2>&1 & echo $!'; pclose(popen($cmd, 'r'));
for windows you may use this:
$cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"'; pclose(popen($cmd, 'r'));
do it yourself with a fork: php also provides the possibility to use forking through the function pcntl_fork(). A good tutorial on how to do this can be found here but i strongly recommend not to use it, since fork is a crime against humanity and especially against oop.
Multithreading
With multithreading all your threads share their resources so you can easily communicate between and synchronize them without a lot of overhead. On the other side you have to know what you are doing, since race conditions and deadlocks are easy to produce but very difficult to debug.
Standard php does not provide any multithreading but there is an (experimental) extension that actually does - pthreads. Its api documentation even made it into php.net. With it you can do some stuff as you can in real programming languages :-) like this:
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!
Download (for Windows PHP 5.3 VC9 TS)
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.
참고URL : https://stackoverflow.com/questions/209774/does-php-have-threading
'development' 카테고리의 다른 글
머티리얼 디자인 아이콘을 안드로이드 프로젝트로 가져 오기 (0) | 2020.07.06 |
---|---|
GitHub로 푸시 오류-저장소 데이터베이스에 객체를 추가 할 수있는 권한이 없습니다 (0) | 2020.07.06 |
AngularJS-ngRepeat 필터링 된 결과 참조를 얻는 방법 (0) | 2020.07.06 |
배경을 투명하게 변환하는 방법? (0) | 2020.07.06 |
wpf에서 버튼 테두리를 어떻게 완전히 제거합니까? (0) | 2020.07.06 |