(PHP7内核剖析-10) 线程安全

news/2024/5/19 2:11:12 标签: php, 数据结构与算法

1.线程安全资源管理器

PHP的SAPI多数是单线程环境,比如cli、fpm、cgi,每个进程只启动一个主线程,这种模式下是不存在线程安全问题的,但是也有多线程的环境,比如Apache,这种情况下就需要考虑线程安全的问题了,因为PHP中有很多全局变量,比如最常见的:EG、CG,如果多个线程共享同一个变量将会冲突,所以PHP为多线程的应用模型提供了一个安全机制:Zend线程安全(Zend Thread Safe, ZTS)。
PHP中专门为解决线程安全的问题抽象出了一个线程安全资源管理器(Thread Safe Resource Mananger, TSRM),实现原理比较简单:既然共用资源这么困难那么就干脆不共用,各线程不再共享同一份全局变量,而是各复制一份,使用数据时各线程各取自己的副本,互不干扰。
typedef struct {
    size_t size; //资源的大小
    ts_allocate_ctor ctor; //初始化函数
    ts_allocate_dtor dtor;
    int done;
} tsrm_resource_type;

struct _tsrm_tls_entry {
    void **storage; //资源数组
    int count; //拥有的资源数:storage数组大小
    THREAD_T thread_id; //所属线程id
    tsrm_tls_entry *next;
};
如果一个资源会被多线程使用,那么首先需要预先向TSRM注册资源,然后TSRM为这个资源分配一个唯一的编号,并把这种资源的大小、初始化函数等保存到一个tsrm_resource_type结构中,各线程只能通过TSRM分配的那个编号访问这个资源;然后当线程拿着这个编号获取资源时TSRM如果发现是第一次请求,则会根据注册时的资源大小分配一块内存,然后调用初始化函数进行初始化,并把这块资源保存下来供这个线程后续使用。
每个线程拥有一个tsrm_tls_entry结构,当前线程的所有资源保存在storage数组中,下标就是各资源的id。另外所有线程的tsrm_tls_entry结构通过一个数组保存:tsrm_tls_table,这是个全局变量,每个线程的tsrm_tls_entry结构在这个数组中的位置是根据线程id与预设置的线程数(tsrm_tls_table_size)取模得到的,也就是说有可能多个线程保存在tsrm_tls_table同一位置,所以tsrm_tls_entry是个链表,查找资源时首先根据:线程id % tsrm_tls_table_size得到一个tsrm_tls_entry,然后开始遍历链表比较thread_id确定是否是当前线程的。

线程本地存储(Thread Local Storage, TLS),在创建完当前线程的tsrm_tls_entry后会把这个值保存到当前线程的TLS中,这样在ts_resource()获取资源时中就可以通过tsrm_tls_get()直接取到了,节省加锁检索的时间。

图片描述


http://www.niftyadmin.cn/n/735353.html

相关文章

Linux安装 metashape

1. 下载软件 3D三维建模软件 Agisoft Metashape Pro 2. 安装 # 进入root模式,如果之前没有设置过密码 sudo passwd # 修改密码 su root # 进入root模式 # 将下载的安装包移动到 /usr/local mv metashape-pro_1_6_5_amd64.tar.gz /usr/local/metashape-pro_1_6_5…

`<script>` 标签与 defer、async 属性

<script> 标签与 defer、async 属性 文章目录简介 在浏览器的运行环下&#xff0c;我们知道要想在网页中插入脚本&#xff0c;我们可以使用 <script> 标签来选择引入内联脚本/外部文件脚本的方式来为网页插入 js。但是脚本的加载和执行时机其实是与 HTML 文件的解…

linux-防火墙设置

防火墙状态 查询防火墙状态 service iptables status 停止防火墙 service iptables stop 启动防火墙 service iptables start 重启防火墙 service iptables restart 永久关闭防火墙 chkconfig iptables off 永久关闭后启动 chkconfig iptables on 关闭防火墙注意 *) 如果要关闭…

JVM汇总--jvm调优-命令篇

2019独角兽企业重金招聘Python工程师标准>>> GC的最根本原因&#xff1a;垃圾收集器的工作就是清除Java创建的对象&#xff0c;垃圾收集器需要清理的对象数量以及要执行的GC数量均取决于已创建的对象数量。因此&#xff0c;为了使你的系统在GC上表现良好&#xff0c…

论文中积累的常用表达

To our best knowledge   据我们所知 Ideally,…   理想情况下 Specifically,…   具体来说 Accordingly,…   因此 With regard to   关于, 相对于 We also enforce that the following frames in a sequence must also be considered static with regard to t…

VScode一些快捷键的简记

全屏和退出   F11 调出终端   ctrl 选择所有出现的当前选择,可进行批量修改   ctrlshiftL 触发参数提示   ctrlshiftspace

python基础—函数式编程

函数式编程 1.不可变数据 2.第一类对象 3.尾调用优化&#xff08;尾递归&#xff09;  1.高阶函数 满足两个条件任意一个为高阶函数&#xff1a; 1.函数的传入参数是一个函数名 2.函数的返回值是一个函数 #非函数式 a 1 def test():global aa 1return a test() print(a)#函数…

Http 缓存: 强缓存与协商缓存

Http 缓存: 强缓存与协商缓存 文章目录Http 缓存: 强缓存与协商缓存简介参考完整示例代码正文Http 缓存机制&#xff1a;强缓存 & 协商缓存强缓存&#xff1a;Expires & Cache-ControlHttp 1.0&#xff1a;ExpiresHttp 1.1&#xff1a;Cache-Control协商缓存&#xff1…