是否有一种可行的方法在PHP中实现多线程模型,无论是真正的,还是只是模拟它。以前曾有人建议,可以强制操作系统加载PHP可执行文件的另一个实例,并同时处理其他进程。

这样做的问题是,当PHP代码完成执行时,PHP实例仍然保留在内存中,因为没有办法从PHP内部杀死它。所以如果你正在模拟几个线程,你可以想象会发生什么。所以我仍然在寻找一种方法,多线程可以在PHP中有效地完成或模拟。什么好主意吗?


当前回答

常规PHP中没有线程,但是通过使用HTTP请求作为异步调用,可以实现并发编程。

将curl的超时设置设置为1,并为您希望相互关联的进程使用相同的session_id,您可以与会话变量通信,如下面的示例所示。使用这种方法,您甚至可以关闭浏览器,而并发进程仍然存在于服务器上。

不要忘记像这样验证正确的会话ID:

http://localhost/test/verifysession.php?sessionid=[正确的id]

startprocess.php

$request = "http://localhost/test/process1.php?sessionid=".$_REQUEST["PHPSESSID"];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo $_REQUEST["PHPSESSID"];

process1.php

set_time_limit(0);

if ($_REQUEST["sessionid"])
   session_id($_REQUEST["sessionid"]);

function checkclose()
{
   global $_SESSION;
   if ($_SESSION["closesession"])
   {
       unset($_SESSION["closesession"]);
       die();
   }
}

while(!$close)
{
   session_start();
   $_SESSION["test"] = rand();
   checkclose();
   session_write_close();
   sleep(5);
}

verifysession.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
var_dump($_SESSION);

closeprocess.php

if ($_REQUEST["sessionid"])
    session_id($_REQUEST["sessionid"]);

session_start();
$_SESSION["closesession"] = true;
var_dump($_SESSION);

其他回答

虽然不能使用线程,但在php中确实有某种程度的进程控制。这里有用的两个函数集是:

过程控制功能 http://www.php.net/manual/en/ref.pcntl.php

POSIX函数 http://www.php.net/manual/en/ref.posix.php

你可以用pcntl_fork来分叉你的进程——返回子进程的PID。然后你可以使用posix_kill来处理这个PID。

也就是说,如果你终止了父进程,就应该向子进程发送一个信号,告诉它终止。如果php本身没有识别这一点,你可以注册一个函数来管理它,并使用pcntl_signal做一个干净的退出。

您可以选择:

multi_curl 可以使用系统命令来实现相同的功能 理想的情况是,用C语言创建一个线程函数,然后用PHP编译/配置。这个函数是PHP的函数。

您可以模拟线程。PHP可以通过popen(或proc_open)运行后台进程。这些进程可以通过stdin和stdout进行通信。当然,这些进程本身也可以是一个php程序。这可能是你能找到的最接近的了。

As of the writing of my current comment, I don't know about the PHP threads. I came to look for the answer here myself, but one workaround is that the PHP program that receives the request from the web server delegates the whole answer formulation to a console application that stores its output, the answer to the request, to a binary file and the PHP program that launched the console application returns that binary file byte-by-byte as the answer to the received request. The console application can be written in any programming language that runs on the server, including those that have proper threading support, including C++ programs that use OpenMP.

一个不可靠的,肮脏的技巧是使用PHP来执行控制台应用程序,"uname",

uname -a

and print the output of that console command to the HTML output to find out the exact version of the server software. Then install the exact same version of the software to a VirtualBox instance, compile/assemble whatever fully self-contained, preferably static, binaries that one wants and then upload those to the server. From that point onwards the PHP application can use those binaries in the role of the console application that has proper multi-threading. It's a dirty, unreliable, workaround to a situation, when the server administrator has not installed all needed programming language implementations to the server. The thing to watch out for is that at every request that the PHP application receives the console application(s) terminates/exit/get_killed.

As to what the hosting service administrators think of such server usage patterns, I guess it boils down to culture. In Northern Europe the service provider HAS TO DELIVER WHAT WAS ADVERTISED and if execution of console commands was allowed and uploading of non-malware files was allowed and the service provider has a right to kill any server process after a few minutes or even after 30 seconds, then the hosting service administrators lack any arguments for forming a proper complaint. In United States and Western Europe the situation/culture is very different and I believe that there's a great chance that in U.S. and/or Western Europe the hosting service provider will refuse to serve hosting service clients that use the above described trick. That's just my guess, given my personal experience with U.S. hosting services and given what I have heard from others about Western European hosting services. As of the writing of my current comment(2018_09_01) I do not know anything about the cultural norms of the Southern-European hosting service providers, Southern-European network administrators.

多线程意味着同时执行多个任务或进程,我们可以通过使用以下代码在php中实现这一点,尽管在php中没有直接的方法来实现多线程,但我们可以通过以下方法实现几乎相同的结果。

chdir(dirname(__FILE__));  //if you want to run this file as cron job
 for ($i = 0; $i < 2; $i += 1){
 exec("php test_1.php $i > test.txt &");
 //this will execute test_1.php and will leave this process executing in the background and will go         

 //to next iteration of the loop immediately without waiting the completion of the script in the   

 //test_1.php , $i  is passed as argument .

}

Test_1.php

$conn=mysql_connect($host,$user,$pass);
$db=mysql_select_db($db);
$i = $argv[1];  //this is the argument passed from index.php file
for($j = 0;$j<5000; $j ++)
{
mysql_query("insert  into  test   set

                id='$i',

                comment='test',

                datetime=NOW() ");

}

这将同时执行test_1.php两次,两个进程将同时在后台运行,因此通过这种方式,您可以在php中实现多线程。

这个人在php多线程方面做得很好