先了解一下process和event loop

EventLoop

除了异步ServerClient库之外,Swoole扩展还提供了直接操作底层epoll/kqueue事件循环的接口。可将其他扩展创建的socketPHP代码中stream/socket扩展创建的socket等加入到SwooleEventLoop中。

事件优先级

  1. 通过Process::signal设置的信号处理回调函数
  2. 通过Event::defer设置的延迟执行函数
  3. 通过Timer::tickTimer::after设置的定时器回调函数
  4. 通过Event::cycle设置的周期回调函数

swoole_event_add函数用于将一个socket加入到底层的reactor事件监听中。此函数可以用在ServerClient模式下

参数

参数1可以为以下四种类型:

  • int,就是文件描述符,包括swoole_client->$sockswoole_process->$pipe或者其他fd
  • stream资源,就是stream_socket_client/fsockopen创建的资源
  • sockets资源,就是sockets扩展中socket_create创建的资源,需要在编译时加入 ./configure --enable-sockets
  • objectswoole_processswoole_client,底层自动转换为管道或客户端连接的socket

参数2为可读回调函数,参数3为可写事件回调,可以是字符串函数名、对象+方法、类静态方法或匿名函数,当此socket可读时回调指定的函数。

参数4为事件类型的掩码,可选择关闭/开启可读可写事件,如SWOOLE_EVENT_READSWOOLE_EVENT_WRITE,或者SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE

  1. Server 程序中使用时,必须在 Worker 进程启动后使用。在 Server::start 之前不得调用任何异步 IO 接口

在fpm当中一个请求结束了线程就被关掉了,注册的事件就不会再去监听了

event lop实例:

命令符聊天室

主要应用点:

异步读取来自副武器的数据

异步读取来自终端的输入

手动退出聊天室

监听服务器的读和写操作

服务端是不会挺停止的

process

PHP自带的pcntl,存在很多不足,如

  • pcntl没有提供进程间通信的功能
  • pcntl不支持重定向标准输入和输出
  • pcntl只提供了fork这样原始的接口,容易使用错误
  • swoole_process提供了比pcntl更强大的功能,更易用的API,使PHP在多进程编程方面更加轻松。

swoole_process提供了如下特性:

  • swoole_process提供了基于unixsock的进程间通信,使用很简单只需调用write/read或者push/pop即可
  • swoole_process支持重定向标准输入和输出,在子进程内echo不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
  • 配合swoole_event模块,创建的PHP子进程可以异步的事件驱动模式
  • swoole_process提供了exec接口,创建的进程可以执行其他程序,与原PHP父进程之间可以方便的通信

curl实例:多进程执行任务和执行一个外部的程序

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: baidu
  5. * Date: 18/3/17
  6. * Time: 上午12:31
  7. */
  8.  
  9. echo "process-start-time:".date("Ymd H:i:s");
  10. $workers = [];
  11. $urls = [
  12. 'http://baidu.com',
  13. 'http://sina.com.cn',
  14. 'http://qq.com',
  15. 'http://baidu.com?search=singwa',
  16. 'http://baidu.com?search=singwa2',
  17. 'http://baidu.com?search=imooc',
  18. ];
  19.  
  20. for($i = 0; $i < 6; $i++) {
  21. // 子进程
  22. $process = new swoole_process(function(swoole_process $worker) use($i, $urls) {
  23. // curl
  24. $content = curlData($urls[$i]);
  25. //echo $content.PHP_EOL;
  26. $worker->write($content.PHP_EOL);
  27. }, true);
  28. $pid = $process->start();
  29. $workers[$pid] = $process;
  30. }
  31.  
  32. foreach($workers as $process) {
  33. echo $process->read();
  34. }
  35. /**
  36. * 模拟请求URL的内容 1s
  37. * @param $url
  38. * @return string
  39. */
  40. function curlData($url) {
  41. // curl file_get_contents
  42. sleep(1);
  43. return $url . "success".PHP_EOL;
  44. }
  45. echo "process-end-time:".date("Ymd H:i:s");
  1. $process = new swoole_process(function(swoole_process $pro) {
  2. // todo
  3. // php redis.php
  4. $pro->exec("/home/work/study/soft/php/bin/php", [__DIR__.'/../server/http_server.php']);
  5. }, false);
  6.  
  7. $pid = $process->start();
  8. echo $pid . PHP_EOL;
  9.  
  10. swoole_process::wait();

process实例:

  1. <?php
  2. class BaseProcess{
  3. private $process;
  4. public function __construct()
  5. {
  6. $this->process = new swoole_process([$this,'run'],false,true);
  7. $this->process->start();
  8. swoole_event_add($this->process->pipe,function($pipe){
  9. $data = $this->process->read();
  10. echo 'RECV: '.$data.PHP_EOL;
  11. });
  12. }
  13.  
  14. public function run($worker){
  15. swoole_timer_tick(1000,function($timer_id){
  16. static $index = 0 ;
  17. $index += 1;
  18. $this->process->write('hello sunlong');
  19. var_dump($index);
  20. if($index == 10){
  21. swoole_timer_clear($timer_id);
  22. }
  23. });
  24. }
  25. }
  26.  
  27. new BaseProcess();
  28. swoole_process::signal(SIGCHLD,function($sig){
  29. while($ret = swoole_process::wait(false)){
  30. echo "PID={$ret['pid']}\n";
  31. }
  32. });

返回结果

  1. [root@localhost php]# php7 process2.php
  2. int(1)
  3. RECV: hello sunlong
  4. int(2)
  5. RECV: hello sunlong
  6. int(3)
  7. RECV: hello sunlong
  8. int(4)
  9. RECV: hello sunlong
  10. int(5)
  11. RECV: hello sunlong
  12. int(6)
  13. RECV: hello sunlong
  14. int(7)
  15. RECV: hello sunlong
  16. int(8)
  17. RECV: hello sunlong
  18. int(9)
  19. RECV: hello sunlong
  20. int(10)
  21. RECV: hello sunlong
  22. PID=2903

上述案例  创建子进程,然后执行定时器,定时器向管道写入数据;swoole_event_add监听管道写事件回调(异步监听管道数据),读取到写的内容并输出。

此时程序还没终止,event loop还在监听管道数据

下面是消息队列作为进程间通信  消息队列同步的 不支持异步

  1. [root@localhost php]# php7 process2.php
  2. int(1)
  3. RECV: hello sunlong
  4. int(2)
  5. RECV: hello sunlong
  6. int(3)
  7. RECV: hello sunlong
  8. int(4)
  9. RECV: hello sunlong
  10. int(5)
  11. RECV: hello sunlong
  12. int(6)
  13. RECV: hello sunlong
  14. int(7)
  15. RECV: hello sunlong
  16. int(8)
  17. RECV: hello sunlong
  18. int(9)
  19. RECV: hello sunlong
  20. int(10)
  21. RECV: hello sunlong

  

升华一下  实现简单的进程池 动态扩展进程池 同时处理更多任务

但是推荐使用swoole_server+task做任务池

swoole_process->exec

process在swoole_server中还是有实际运用的,比如执行脚本或者shell命令,linux的tail,top,ps持续的命令,通过管道实时监听,展示在网页上,做成一个外部监控器(process应用)

task执行一个长耗时任务,

两者有重叠但是也有区别

Event IO Process的更多相关文章

  1. 泛函编程(38)-泛函Stream IO:IO Process in action

    在前面的几节讨论里我们终于得出了一个概括又通用的IO Process类型Process[F[_],O].这个类型同时可以代表数据源(Source)和数据终端(Sink).在这节讨论里我们将针对Proc ...

  2. 泛函编程(35)-泛函Stream IO:IO处理过程-IO Process

    IO处理可以说是计算机技术的核心.不是吗?使用计算机的目的就是希望它对输入数据进行运算后向我们输出计算结果.所谓Stream IO简单来说就是对一串按序相同类型的输入数据进行处理后输出计算结果.输入数 ...

  3. 泛函编程(37)-泛函Stream IO:通用的IO处理过程-Free Process

    在上两篇讨论中我们介绍了IO Process:Process[I,O],它的工作原理.函数组合等.很容易想象,一个完整的IO程序是由 数据源+处理过程+数据终点: Source->Process ...

  4. Understanding Asynchronous IO With Python 3.4's Asyncio And Node.js

    [转自]http://sahandsaba.com/understanding-asyncio-node-js-python-3-4.html Introduction I spent this su ...

  5. IO网络模型

    多路处理模型MPM MPM是Apache2引入的一个概念,就是将结构模块化.把核心任务处理作为一个可插拔的模块,使其能针对不同的环境进行优化 在这个情况下,就诞生出了处理模式的概念 Prefork 实 ...

  6. Linux Process VS Thread VS LWP

    Process program program==code+data; 一个进程可以对应多个程序,一个程序也可以变成多个进程.程序可以作为一种软件资源长期保存,以文件的形式存放在硬盘 process: ...

  7. 一步步使用BMC Atrium Orchestrator Vmware Infrastructure Event Monitor

    本教程将一步步演示怎么使用BMC Atrium Orchestrator (BAO) Vmware Infrastructure Event Monitor来监控VSphere Webservice的 ...

  8. process.nextTick

    回调函数同步执行 function asyncFake(data, callback) { if(data === 'foo') { callback(true); }else{ callback(f ...

  9. 进程Process之join、daemon(守护)、terminate(关闭)、multiprocessing之锁、信号量和事件

    一.Process 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'a',) ...

随机推荐

  1. Java volatile 有什么作用

    在由Java语言编写的程序中.有时候为了提高程序的执行效率,编译器会自己主动对其进行优化,把经常被訪问的变量缓存起来,程序在读取这个变量的时候有可能会直接从缓存(比如寄存器)中来读取这个值.而不会去内 ...

  2. WebGIS前端地图显示之根据地理范围换算出瓦片行列号的原理(核心)

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或 ...

  3. Dalvik VM 和JVM的比较

    避免出现版权问题android重写JVM 两者在编译后的文件格式区别: JVM: .java->.class->.jar DALVIK VM:.java->.class->.d ...

  4. 深入理解char * ,char ** ,char a[ ] ,char *a[]

    1.数组的本质 数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素. 2.指针 指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址.由于地址也 ...

  5. 【Python】【进程&线程】

    #[[进程 和 线程 ]] """ # [多进程]'''import os print ('Process (%s) start...' % os.getpid()) # ...

  6. 【Selenium2】【项目实战】

    [public/login.py] from selenium import webdriverfrom selenium.webdriver.common.by import Byimport ti ...

  7. ubuntu 安装pip3 遇到Ignoring ensurepip failure: pip 8.1.1 requires SSL/TLS错误

    3.5版本之后的会自动安装pip,所以我们直接从官网下载3.5.2,下载地址:https://www.python.org/ftp/python/ 下载以后,可以用命令解压,也可以右键进行解压, ta ...

  8. javaSE习题 第二章 基本数据类型和数组

    问答: 1.什么叫标识符,标识符的规则是什么? 用来标志类名,变量名,方法名,类型名,数组名,文件名的有效字符序列称为标识符. 规则:1.由字母,数字,下划线,美元组成.2.标识符第一个字符不能是数字 ...

  9. Promise的.then .catch

    定义一个promise 调用promise  如果promise的状态为resolve 则 执行 .then   否则执行.catch 可以有多个.then  会按顺序执行 axios.post  可 ...

  10. java与js交互,相互调用传参

    随着前端技术的发展与H5的广泛使用,移动端采用native+h5的方式越来越多了,对于Android来说就涉及到java与js的交互,相互调用传参等.下面就来看一下java与js交互的简单demo. ...