首先看每一个的定义:
cgi:
CGI全称是“通用网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序一般运行在网络服务器上。 CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。

FastCgi
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。它还支持分布式的运算, 即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。
FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器(php-cgi)保持在内存中并接受FastCGI进程管理器(php-fpm)调度,则可以提供良好的性能、伸缩性、Fail- Over特性等等。

php-cgi
1.PHP的解释器。php-cgi只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理(网上一直说php-cgi是5.4之前时期的FastCGI的管理器,其实不是)
2.php.ini修改之后,必须kill掉php-cgi再启动php.ini 才生效,不可以平滑的重启
3.启动php,指定启动的worker ,长期驻留在内存里 ,用户访问php文件,php-cgi 处理请求,返回结果

php-fpm
1.非官方 实现fastCgi协议的进程--php-cgi的管理器,后来php5.4开始,被官方收录了。 fastCgi是协议,php-cgi是进程,php-fpm严谨的来讲是管理实现fastcgi协议的php-cgi进程的管理器。
2.平滑重启php,新的worker用新的配置,已经存在的worker处理完手上的活就可以歇着了,通过这种机制来平滑过度。
3.长期驻留在内存里 ,根据来访压力动态增减worker的进程数量(动态分配内存,实现fastcgi),用户访问php文件, php-fpm 处理请求,返回结果

fastcgi、cgi运行步骤:
1、Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module或者nginx php-fpm)
2、FastCGI进程管理器自身初始化,启动多个CGI解释器进程php-cgi(可建多个php-cgi)并等待来自Web Server的连接。
3、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。
在CGI模式中,php-cgi在此便退出了,会在下一次请求时重新开启。
在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

这里是模拟一台主机发出请求,访问php程序,中间的流程。
首先说明,web server(比如说apache,nginx)是内容(文件,数据)的分发者。
如果请求index.html静态文件,那么web server会去文件系统中找到这个文件,发送给请求的浏览器。
但如果请求的是index.php动态页面,根据配置文件,web server判断这个不是静态文件,如果是,则直接分发静态页面。如果不是,则需要去找PHP解释器(php-cgi)来处理,那么他会把这个请求处理后(cgi协议规则处理后)交给PHP解释器(php-cgi)。web server会传哪些数据给PHP解释器(php-cgi)呢,这里,CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议。
如果是cgi,接下来PHP解释器(php-cgi)会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。(每个请求执行一次!)。
如果是fastcgi,首先,Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是fastcgi协议对进程的管理,而实现fastcgi协议的就是php-fpm。

说的很绕,总结一下。cgi、fastcgi都是协议,fastcgi是cgi的优化升级(长驻版),php-cgi是php的解释器,php-fpm是实现fastcgi的进程管理工具,管理的是php-cgi。