当前位置:首页 > PHP > php相关文章

PHP pcntl-多线程与多进程区别

2021-03-17 来源:网络 作者:无名网

pcntl是一个可以利用操作系统的fork系统调用在PHP中实现多线程的进程控制扩展,当使用fork系统调用后执行的代码将会是并行的。pcntl仅适用于Linux平台的CLI模式下使用。

PHP官方没有提供多线程的扩展,在pecl中有一个pthread扩展提供了多线程的特性,此版本仅在线程安全版本中可用。

创建子进程pcntl_fork

int pcntl_fork(void)

pcntl_fork函数执行时会在当前进程下创建一个子进程,子进程与父进程在PID和PPID上会不同。

子进程会复制父进程中所有的数据、代码、状态等信息。当使用pcntl_fork成功创建子进程后,子进程会复制父进程的代码和数据。此时父进程和子进程拥有相同的代码和数据。子进程也会复制父进程的状态。

当使用pcntl_fork创建子进程,如果成功则会在父进程中将会返回0,在子进程中会返回自身的进程编号PID。如果创建失败则返回-1

使用pcntl_fork创建的进程只是一个分支节点,相当于一个标记,父进程完成后子进程会从标记处继续执行,也就是说在pcntl_fork之后的代码分别会被父进程和子进程执行两遍,而两个进程在执行过程中得到的返回值却是不同的,因此才可以分离父子进程执行不同的代码。

在Linux环境下可使用ps命令查看进程

<?php
$pid = pcntl_fork();if($pid > 0){
//父进程
exit(0);
}elseif($pid == 0){
//子进程
exit(0);
}

多进程与多线程的区别

多进程和多线程的作用相同,区别主要在于

  • 多个线程是在同一个进程内的,线程之间可以共享内存变量而实现线程间的通信。

  • 线程比进程更加轻量级,进程要比线程更加消耗系统资源。

多线程存在的问题主要有

  • 线程读写变量存在着同步问题需要加锁

  • 锁粒度过大会存在性能问题,会导致只有一个线程在运行,其它线程都在等待锁,也就无法实现并行。

  • 同时使用多个锁时逻辑复杂,一旦某个锁没有被正确释放可能会发生线程死锁。

  • 某个线程发生致命错误会导致整个进程崩溃

相对而言多进程更为稳定,可利用进程间通信IPC技术实现数据共享。多进程通信的方式主要包括

  • 共享内存
    共享内存和线程间读写变量时一样的,都需要加锁,同时也存在同步、死锁等问题。

  • 消息队列
    消息队列采用多个子进程抢占队列的模式,性能较好。

  • 管道、UnixSock、TCP、UDP
    可以使用read/write来传递数据,TCP/UDP使用socket来通信,子进程可以分布运行。

利用fork系统调用可以实现并发的TCP服务器,主进程accept客户端连接。当有新的连接到来时直接fork一个子进程,子进程中循环recv/send处理数据。这种模式在请求量不多的情况下很实用,例如FTP服务器。

在过去多数Linux程序都时采用这种模式,简单高效,代码量少。当有几百个并发的情况下表现不错,但在大并发的情况下消耗就会过大。

例如:每个子进程都能创建一个与之对应的文件,父进程也创建一个属于自己的文件。

<?php
    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
    if($socket < 0){
    $errmsg = socket_strerror($socket);
    echo "failed to create socket: {$errmsg}".PHP_EOL;
    exit;}$host = "0.0.0.0";$port = 9601;$ret = socket_bind($socket, $host, $port);if($ret < 0){
    echo "failed to bind socket: {$ret}".PHP_EOL;
    exit;}$ret = socket_listen($socket, 0);if($ret < 0){
    $errmsg = socket_strerror($ret);
    echo "failed to listen: {$errmsg}".PHP_EOL;
    exit;}while(pcntl_fork() == 0){
    $connection = @socket_accept($socket);
    if(pcntl_fork() == 0){
        $recv =  socket_read($connection ,8192);
        $data = "serverr: {$recv}";

        socket_write($connection ,$data);
        socket_close($connection);
        exit(0);
      }else{
        socket_close($connection);
      }
  }


相关内容: php 进程 线程
『 猜你喜欢 』
  • strstr函数-php

    strstr (PHP 4, PHP 5, PHP 7, PHP 8) strstr — 查找字符串的首次出现 说明 strstr ( string $haystack

  • php是什么_php能做什么

    PHP 能做任何事。PHP 主要是用于服务端的脚本程序,因此可以用 PHP 来完成任何其它的 CGI 程序能够完成的工作,例如收集表单数据,生成动态网页,或者发送/接收

  • PHP需要些什么?

    在本教程中,假设用户的服务器已经安装并运行了 PHP,所有以.php结尾的文件都将由 PHP 来处理。在大部分的服务器上, 这是 PHP 的默认扩展名,不过,也请询问

  • PHP实用的脚本

    现在来编写一些更实用的脚本,比如检查浏览页面的访问者在用什么浏览器。要达到这个目的,需要检查用户的 agent 字符串,它是浏览器发送的 HTTP 请求的一部分。该信息

  • 在新版本的 PHP 中使用旧的 PHP 代码

    现在,PHP 已经发展成为一种流行的脚本语言,可以在很多公共的资源里找到可以在自己的脚本中重新利用的代码。PHP 语言的开发者为向下兼容性下了很多功夫,因此在新版本的

  • php从 HTML 中分离

    凡是在一对开始和结束标记之外的内容都会被 PHP 解析器忽略,这使得 PHP 文件可以具备混合内容。 可以使 PHP 嵌入到 HTML 文档中去,如下例所示。 pThi

  • php支持的数据类型

    PHP 支持 10 种原始数据类型。 四种标量类型: bool (布尔型) int (整型) float (浮点型,也称作 double ) string (字符串)

  • 如何看待PHP这门备受争议的语言

    个人亲身体验。php估计是目前存在争议最大的语言了,争议(甚至往往还带有一些嘲讽)声一直不绝于耳。但是却没有影响它成为最流行的语言之一,至少在我写这篇文章时它还是一门非

  • phpstorm php7特性报错解决方法(coalesce operator is available in PHP7 only)

    解决方法。使用phpstorm开发时,偶尔会出现以下报错:coalesce operator is available in PHP7 only1、打开phpstorm

  • windows安装php-php线程安全和非线程安全

    1、windows + IS + FastCGl : 使用非线程安全版本。,2、windows +IIS +ISAPI : 使用线程安全版本,3、windows + A