PHP, 编程

PHP线程安全与非线程安全版本的本质区别

php

在百度上搜“PHP 线程安全 非线程安全”,你肯定会找到这种狗屁话:

php-some

一本正经说胡话,完完全全没解释到点上。

稍微懂点C语言的都不会相信这种话,更别谈说出来了,千转载万转载你转载我我转载你就转载点那么没水平的东西来忽悠人。

 

线程和进程最大的根本区别就是内存数据的共享。

每个进程都独享一个虚拟内存[虚拟内存 = 物理内存 + SWAP/页面文件)]。

一个进程可以拥有多个线程,一般来说一个线程仅独享一个进程的虚拟内存中的一个函数栈帧。

 

程序储存数据有下面几种常用的方式:

自动变量: 自动变量是储存在栈中的,随着函数的调用而产生,结束而销毁。

静态(全局)变量: 静态分配的变量是随着程序的运行产生,程序的结束而销毁,这些变量储存在内存一个专门存放静态变量的区域。

堆: 即通过malloc()申请的内存,一旦申请后,直到调用free(),或程序结束后才释放。

 

其中造成“非线程安全”的主要是静态变量以及堆。

自动变量仅存在于函数自己的栈中,不管你如何修改其值,均不会影响其他函数(准确来说是线程)的数据。

静态变量独立储存于一个区域,这就意味着一个静态变量由整个进程的所有线程共享,一个线程修改了静态变量的值,将会改变其他线程读对该变量取得的结果,储存于堆的数据亦如此。

 

所谓“线程安全”,即采取了的措施,避免不同的线程同时对一个变量进行修改。

例如某些函数的结果保存于静态分配的变量,或者是保存于堆中的一个区域,可以选择通过加锁,或互斥量来阻塞其他线程对这些函数的调用,但细心的话你也看到了“阻塞”二字,因此最佳的办法就是避免采用这些用到静态分配或堆的函数。

 

如果你用过PHP的Pthreads模块,并且理解了本文,那你应该明白为何Pthreads模块强制要求使用线程安全版本的PHP。

(91 Posts)

自信、努力、活出精彩;以前未所见的颜色,绘大千世界!

View all author’s posts

Leave a reply