关于线程和进程的疑问

2015-12-18 11:19:00 +08:00
 ben548

之前在做 php 的开发时从来没有想过线程的问题(野生程序员的悲哀),最近在看朴灵写的《深入浅出 nodejs 》时,第九章提到了进程和线程。

1 、对于这两个概念我一直很模糊,在网上查到的资料是阮一峰写的一篇文章,他把一个进程比作一间工厂,一个线程比作工厂里面的工人,那么是不是可以这么理解,一个进程可以包含多个线程,开启多进程主要是为了实现多 cpu 的最大利用化呢?

2 、还有我了解到 php 是不支持多线程的,那么在多人访问网站的情况下不是会造成阻塞吗?但是事实上我们在浏览网站的时候好像并没有什么阻塞的情况发生啊?是因为 apache 做了什么吗?

3 、另外 apache 和 nginx 处理 php 请求上有什么区别呢?为什么现在的网站都趋向于使用 nginx ,而不是 apache ,我对这两者的理解,只有 apache 是通过模块调用的方式来处理 php 请求的,而 nginx 则是将 php 请求转发到了 php-fastcgi 上面。

4856 次点击
所在节点    PHP
31 条回复
cxe2v
2015-12-18 11:28:06 +08:00
1.多进程并行需要多个 CPU 核心同时处理才能体现优势,但线程的优点不止这个
2.你猜对了,是 apache 做了些什么,简略的说就是来一个请求, apache 就开一个线程来处理
3.我不知道
shippo7
2015-12-18 11:34:30 +08:00
一个程序运行时至少要有一个进程,一个进程可以包含多个线程

多个线程之间可以通信(使用共享内存),使得多线程可以处理同一个任务。例如使用多个线程压制影片。

多个进程之间不可以直接通信(使用独立内存地址),例如开两个 VLC 播放器窗口播放不同影片,还有 Chrome 的每个标签页使用独立进程。
ben548
2015-12-18 11:43:51 +08:00
@shippo7 Chrome 的每个标签页使用独立进程? 按照我的理解,是不是一个 cpu 只能开一个进程呢?如果是的话,那么 chrome 的标签页的数量是有限制的?是不是我理解错了呢
mthli
2015-12-18 11:47:43 +08:00
@ben548 可以去了解一下 CPU 的任务调度。并不是说一个 CPU 只能开一个进程的。
mahone3297
2015-12-18 11:48:12 +08:00
@ben548 1 个 cpu 怎么会只能开 1 个进程?
那单核的机器,不都只能运行 1 个进程了?
系统起来,就有很多进程了。。。大家按时间片切换去使用 cpu ,同一时间, 1 个核只能处理 1 个进程,应该是这样。
akira
2015-12-18 11:48:45 +08:00
@ben548 理解有偏差。 cpu 数和进程数没有关系。
huhao
2015-12-18 11:48:59 +08:00
楼主既然已经有了线程和进程的疑问了,说明已经到了一个阶段了,那么在这个阶段下,我个人建议先不要去看 nodejs 这种,先去学一门强类型的语言,比如 C 和 JAVA ,然后再去翻一翻操作系统概念或 CSAPP 之类的书,总结一下就是,可以开始去通底层了
shippo7
2015-12-18 11:49:28 +08:00
@ben548 CPU 的多任务机制允许一个 CPU 核心运行多个进程。最早的 DOS 系统是单任务,也就是一个 CPU 运行一个进程。现代操作系统允许多个进程轮流使用 CPU 时间,每个进程使用 CPU 的时间很短,每个进程从等待队列被放入 CPU 中运行,然后再进入等待队列,直到一个进程的任务结束。这就是打开 Windows 任务管理器,可以看到几十个进程同时运行的原因。
xylophone21
2015-12-18 11:49:44 +08:00
都是多条线“同时”跑,你可以简单的理解成多个入口函数并行的在运行。

但线程是共享内存地址空间的,也就是说 A 线程里的一个变量, B 线程可以直接拿来用。

进程的的内存地址空间是隔离的,也就是说即使同一个变量,也是各用各的,互不影响。如果一定要影响,就需要特殊的手法。
mthli
2015-12-18 11:49:51 +08:00
@ben548 好像之前我这么说也不太准确。总之和至少和(操作系统的)任务调度有关了。
shippo7
2015-12-18 11:54:49 +08:00
关于线程与进程的问题,建议看《操作系统概念》这本书
MForever78
2015-12-18 12:57:55 +08:00
@shippo7 说得对,要想深入了解,《操作系统概念》这本书才是正解。阮一峰写的那篇文章举工厂的例子来尝试说明进程和线程,对懂的人来说很好理解,如果本来就什么都不明白的话看了还是不知所云。

不过因为正好刚学过,我尝试解释一下。进程是指正在运行的一个程序,不仅仅包含这个程序的代码( code ),数据( data ),文件,还包括当前的运行状态,即指令( Program Counter ),栈,和当前 CPU 寄存器的值(有时还包括堆)。新创建一个进程需要在内存中创建以上所有内容。对于 Web Server 来说,服务不同连接的代码、数据、文件都是相同的,只是运行状态不同。所以对每个连接都重新创建进程会造成资源浪费。

而线程基本上就是对进程的代码、数据、文件进行重用,每个线程只是保存了不同的运行状态。于是节省了资源。

另一方面,单个 CPU 同一时间只能执行一条指令,即只能运行一个进程。为了让系统能「看起来」在同时进行多个进程, CPU 需要不断地在进程之间切换。这就是 Multiprogramming 的概念。而进行进程切换的时候不但需要把 CPU 的当前指令指针( Program Counter )切换到下一个进程,并且需要保存当前进程的运行状态,载入下一个进程上次被中断时的运行状态。这部分时间其实 CPU 是没有做什么对程序来说有意义的事情的,称为进程切换的开销( Overhead )。

线程之间的切换代价要小于进程之间的切换代价,因此使用线程节省了时间。
liuxu
2015-12-18 13:09:25 +08:00
进程是从系统拿资源,线程从进程中拿资源。
mitoop
2015-12-18 13:16:18 +08:00
最近也在思考这个问题,看来非要操作系统概念来一下了
ryd994
2015-12-18 13:17:48 +08:00
@MForever78 其实上因为虚拟内存,多个进程之间,代码和文件也是可以做到不影响性能的共享的。特别是 Linux 下 fork 是 cow 的,浪费更是相当小。所以多进程相比多线程的好处,主要还是在内存隔离。
BOYPT
2015-12-18 13:23:53 +08:00
多进程多线程,实质上是任务调度方式。具体要看在什么环境下讨论,事实上上面说的很多线程、进程的特点,在特定环境下都存在特殊情况,特别在 linux 环境下,线程进程的区别非常小。

在 PHP 范畴,如果是指 PHP 做 web 的,因为前端的 apache/nginx 的多线程 /多进程 /异步模型已经封装好了这些需要并发的过程,到达你的 php 代码时候,只是需要 php 完成最后的实际任务而已,所以 php 不需要多线程。

PHP 除了做 web 以外,其实还可以做桌面应用的,只是比较少见,比如用 php-gtk 写图形界面,那就得在 php 内调用线程库接口来实现多线程了,因而也不能说 php 没有多线程,实质上有没有多线程跟语言本身关系不是很大,因为不管什么语言,最终都成为操作系统里面一个进程,调用是操作系统的 api 。
wy315700
2015-12-18 13:28:14 +08:00
深入理解计算机系统 推荐看这本书
ben548
2015-12-18 13:45:43 +08:00
@BOYPT 因为前端的 apache/nginx 的多线程 /多进程 /异步模型已经封装好了这些需要并发的过程 并不完全认同你的看法,如果真的 apache 和 nginx 处理了并发的过程,那边我们为什么在程序开发的过程中需要考虑并发的问题,比如说秒杀等功能的实现?需要用到队列和锁等机制
JmmBite
2015-12-18 13:54:57 +08:00
公路的 “单向单车道” 与 “单向多车道”的区别。
队列就是公路收费口。
iyaozhen
2015-12-18 13:58:12 +08:00
试着回答一下:
1 、可以这么理解,一个进程可以有很多线程。多进程可以很好的利用 CPU 。

2 、 3 、是的, Apache 和 Nginx 做了很多事情。
Apache+php_module 是父进程+子进程的模式,每个访问请求会生成子进程,就不会有阻塞了。
Nginx+PHP-FPM 的话感觉 Nginx 和 PHP 相互独立了, Nginx 遇到自己处理不了的请求就会给 PHP-FPM ( PHP FastCGI 管理器)处理,每来一个请求就会交给一个子进程去处理(这里根据 PHP 的运行配置不同效果也不同,子进程的数量可以是固定的也可以动态生成),然后 Nginx 对交给 PHP-FPM 进行轮训( epoll 机制)。这样处理性能和资源占用都比 Apache 有优势。

楼主可能也对 PHP MySQL 持久连接感兴趣: https://iyaozhen.com/php-mysql_pconnect-discuss.html (硬 SEO )

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/244403

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX