Closed matyhtf closed 1 month ago
目前向子线程传递参数的实现方式是 serialize 串化,在序列化前需要对数组遍历,提取其中的 stream、cosocket 进行 dup(fd) 操作,而反序列化则需要根据 resource id 查询一个全局表获取资源。
serialize
stream
cosocket
dup(fd)
resource id
这种实现存在诸多问题,应该将 thread arguments 改为 ArrayList 类型即可解决所有问题。
thread arguments
ArrayList
// 修改后 $threadArgs 将变为 Thread\ArrayList 对象 $threadArgs = Thread::getArguments(); $thread = new Thread(__FILE__, $fp, $array, $string); // 线程参数将作为 ArrayList 的元素,逐个 append 到 ArrayList 中
$map = new Thread\Map; $map['key1'] = new Thread\Map; $map['key1']['key2'] = new Thread\ArrayList; $map['key1']['key2'][] = 'hello world';
对写入线程数据容器的元素使用 arary_is_list() 判断:
arary_is_list()
true
false
Map
此数组中可以是多维的,也可以包含 stream、cosocket 或 Map、ArrayList 等线程资源。
多维数组
Lock
Atomic
php
保持序列化/反序列化的处理方式
? 是否有必要实现跨线程的 zend_string (persistent) 封装
zend_string (persistent)
目前的考虑是暂时不改,依然使用深拷贝的方式,复制到线程数据容器。主要原因是 PHP 层面只能封装为一个对象 Thread\String,要对这个对象作为字符串操作时,依然要进行一次 toString() 的深拷贝,无法直接作为 string 类型。意义并不大。
PHP
Thread\String
toString()
string
不过在互相赋值时,Thread\String 可以节约内存拷贝的性能开销。例如:
$map = new Thread\Map; $str = random_bytes(1024); $str = new Thread\String(random_bytes(1024)); $map['key1'] = new Thread\Map; $map['key1']['key2'] = $str; $list = new Thread\ArrayList; $list[] = $str;
例子中,$str 被插入了两个数据容器中,若使用原生 string 类型,需要拷贝 2 次,Thread\String 只需要 1 次。如果频繁在多个线程之间互相传递字符串内容,则 Thread\String 的方式性能会更好。
$str
2
1
目标
1. 参数传递与线程数据共享的实现方式统一
目前向子线程传递参数的实现方式是
serialize
串化,在序列化前需要对数组遍历,提取其中的stream
、cosocket
进行dup(fd)
操作,而反序列化则需要根据resource id
查询一个全局表获取资源。这种实现存在诸多问题,应该将
thread arguments
改为ArrayList
类型即可解决所有问题。2. 允许嵌套结构
3. array 类型在存入线程数据容器中时自动转为 Map、ArrayList
对写入线程数据容器的元素使用
arary_is_list()
判断:true
,则转为ArrayList
类型对象进行存储false
,则转为Map
类型对象进行存储此数组中可以是多维的,也可以包含
stream
、cosocket
或Map
、ArrayList
等线程资源。多维数组
:在转为Map
、ArrayList
时会进行递归式的深度遍历Map
、ArrayList
、Lock
、Atomic
等线程资源,仅增加一次引用计数,在php
层代码读写均为浅拷贝stream
、cosocket
进行dup(fd)
操作存入线程数据容器4. Object 类型
保持序列化/反序列化的处理方式
5. String 类型
? 是否有必要实现跨线程的
zend_string (persistent)
封装目前的考虑是暂时不改,依然使用深拷贝的方式,复制到线程数据容器。主要原因是
PHP
层面只能封装为一个对象Thread\String
,要对这个对象作为字符串操作时,依然要进行一次toString()
的深拷贝,无法直接作为string
类型。意义并不大。不过在互相赋值时,
Thread\String
可以节约内存拷贝的性能开销。例如:例子中,
$str
被插入了两个数据容器中,若使用原生string
类型,需要拷贝2
次,Thread\String
只需要1
次。如果频繁在多个线程之间互相传递字符串内容,则Thread\String
的方式性能会更好。