PHP多进程&闭包

来源:互联网 发布:松下网络摄像机默认ip 编辑:程序博客网 时间:2024/06/10 19:50

多进程:入门

1.场景

  1. 异步进程
  2. 并行计算
  3. 守护进程

    • 这个模块没有非Unix平台可用的函数(即非Unix类系统不支持此模块)
    • 进程控制不能被应用在Web服务器环境,当其被用于Web服务环境时可能会带来意外的结果。因此,不能再PHP Web开发中使用多进程。

2.代码段示例

<?php    $ppid = posix_getpid();    $pid = pcntl_fork();    if ($pid == -1) {       throw new Exception('fork子进程失败!');    } elseif ($pid > 0) {       cli_set_process_title("i'm father process,my process id is{$ppid}.");       sleep(20);    } else {      $cpid = posix_getpid();      cli_set_process_title("Im {$ppid} `'s son ,my process id is{$cpid}.");      sleep(20);    }    ?>

3.子进程管理

我们通过在父进程接收子进程传来的信号,判断子进程状态,来对子进程进行管理。

4. 关于declare(ticks=N)详解(http://blog.csdn.net/udefined/article/details/24333333)

一般用法是 declare(ticks=N);
拿declare(ticks=1)来说,这句主要作用有两种:

  1. Zend引擎每执行1条低级语句就去执行一次 register_tick_function() 注册的函数。
    可以粗略的理解为每执行一句php代码(例如:$num=1;)就去执行下已经注册的tick函数。

““

5.子进程与父进程关系

  • 操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。

  • 可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因,至于那一个最先运行,可能与操作系统(调度算法)有关。

重要函数

  • pcntl_fork

  • pcntl_signal_dispatch

    pcntl_signal_dispatch — 调用等待信号的处理器

  • pcntl_signal

    pcntl_signal — 安装一个信号处理器

  • pcntl_wait

    pcntl_wait — 等待或返回fork的子进程状态

  • pcntl_alarm

    创建一个计时器,在指定的秒数后向进程发送一个SIGALRM信号。每次对 pcntl_alarm()的调用都会取消之前设置的alarm信号。

6.应用举例

  1. 当一个文件包含许多任务(每个任务一行),并且各任务之间不存在执行的先后顺序关系,可以将文件进行分割(分割后的文件数量与进程数一致),然后使用多进程进行处理。

    例如,现在有10个邮箱账号存储在文件mailist.txt中,每次发送邮件需要耗时2s,则
    采用单进程依次发送完这些邮件需要耗时20。
    如果采用多进程,例如3个进程进行处理,首先需要将文件按行数拆分成3个小文件,其中两个文件是4条记录,一个文件是2条记录。每个进程处理一个小文件,则不同进程发送完邮件的耗时为8、8、6,总耗时取最大值为8s。

7.参考资料

  • PHP中利用pcntl进行多进程并发控制

  • php多进程使用场景

  • fork函数

  • fork举例

匿名函数&闭包

1. PHP对匿名函数的支持

  1. php5.3有一个非常赞的新特性,那就是支持匿名函数(闭包)。匿名函数可用于动态创建函数,并保存到一个变量中。


$func = function() {
exit('Hello world!!');
};//这里必须要有;结尾
$func();

等价于:

function func() {
exit('Hello world!!');
}
func();

  1. 将匿名函数放在普通函数中,也可以将匿名函数返回,这就构成了一个简单的闭包


//匿名函数中使用局部变量,这时候就要引用一个php的关键字 use,
function closureFunc2(){
$num = 1;
$func = function() use($num){
echo $num;
};
$func();
}
closureFunc2();

  1. 把匿名函数当作参数传递

““
function callFunc(func){func(“argv”);
}

callFunc(function(str){  
    echo
str;
})
//输出:
// argv
““

  1. 调整数组中的数值

““
data=range(0,100);//.htmlsuffix = ‘.html’;

function makeSuffix($str, $suffix){    return $str . $suffix;}$new_data = array_map(function($item) use ($suffix) {    return makeSuffix($item, $suffix);}, $data);

““

5.需要改变数据的结构

““
$arr = [
[
‘id’=>”,
‘name’=>”,
‘create_time’=>”,
],
];

newdata=arraymap(function(item) {
return [‘id’=>item[id],name=>item[‘name’]];
}, $arr);
//如果是用foreach还需要在循环里面建立零时变量,把需要的值赋给这个变量
““

6.array_walk 与闭包

““
public function getTotal(tax)  
    {
total = 0.00;

    $callback =        function ($quantity, $product) use ($tax, &$total)        {            $pricePerItem = constant(__CLASS__ . "::PRICE_" .                strtoupper($product));            $total += ($pricePerItem * $quantity) * ($tax + 1.0);        };    //使用用户自定义函数对数组中的每个元素做回调处理    array_walk($this->products, $callback);    return round($total, 2);;}

““

「闭包」和「匿名」这两个概念并不等价(虽然 PHP 里面对应的都是同一个东西)。匿名是指这个函数可以像变量一样操作,例如可以赋值给另一个变量、作为参数传递、作为函数的返回值等。闭包是指这个函数可以从上下文中捕获变量(而不是通过参数来传递),具体到 PHP 上就是 use 这个子句做的事情。

自动加载

1. __autoload

2.spl_autoload_register()

原创粉丝点击