百度来的概念:
关于进程:
进程的出现是为了更好的利用CPU资源使到并发成为可能。 假设有两个任务A和B,当A遇到IO操作,CPU默默的等待任务A读取完操作再去执行任务B,这样无疑是对CPU资源的极大的浪费。聪明的老大们就在想若在任务A读取数据时,让任务B执行,当任务A读取完数据后,再切换到任务A执行。注意关键字切换,自然是切换,那么这就涉及到了状态的保存,状态的恢复,加上任务A与任务B所需要的系统资源(内存,硬盘,键盘等等)是不一样的。自然而然的就需要有一个东西去记录任务A和任务B分别需要什么资源,怎样去识别任务A和任务B等等。登登登,进程就被发明出来了。通过进程来分配系统资源,标识任务。如何分配CPU去执行进程称之为调度,进程状态的记录,恢复,切换称之为上下文切换。进程是系统资源分配的最小单位,进程占用的资源有:地址空间,全局变量,文件描述符,各种硬件等等资源。
关于协程:
协程通过在线程中实现调度,避免了陷入内核级别的上下文切换造成的性能损失,进而突破了线程在IO上的性能瓶颈。 当涉及到大规模的并发连接时,例如10K连接。以线程作为处理单元,系统调度的开销还是过大。当连接数很多 —> 需要大量的线程来干活 —> 可能大部分的线程处于ready状态 —> 系统会不断地进行上下文切换。既然性能瓶颈在上下文切换,那解决思路也就有了,在线程中自己实现调度,不陷入内核级别的上下文切换。说明一下,在历史上协程比线程要出现得早,在1963年首次提出, 但没有流行开来。
我们在实际使用中,做一个简单的性能测试, 使用两种方式同时往文件里写内容,其中有1秒的延迟`
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php // 协程测试 $baginTime = time(); for ($i = 0; $i <= 10; $i++) { go(function ()use ($i,$baginTime){ for ($j = 0; $j <= 100; $j++) { co::sleep(1); @file_put_contents(__DIR__.'/test/'.$i.'.log', $j.PHP_EOL,FILE_APPEND) .PHP_EOL; if($j == 100 && $i=10) { print_r('协程共耗时:=>'.(time()-$baginTime).'秒'); } } }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php /** * Created by PhpStorm. * User: iyahe@qq.com (天明) * Date: 2018/12/13 0013 * Time: 下午 14:30 */ // 进程测试 $baginTime = time(); $work_number=10; //开启10个进程 $worker=[]; // 记录workId for ($i=0; $i <= $work_number; $i++) { $pro = new swoole_process(function()use($i,$baginTime) { for ($j = 0; $j <= 100; $j++) { sleep(1); file_put_contents(__DIR__.'/test/'.$i.'-0.log', $j.PHP_EOL,FILE_APPEND) .PHP_EOL; if($j==100 && $i=10) { print_r('进程共耗时:=>'.(time()-$baginTime) .'秒'); } } }); $pro_id = $pro->start(); $worker[$pro_id]=$pro; } //进程回收 swoole_process::wait(); |
最终:进程共耗时:=>101,协程共耗时:=>102!