share_value
基础说明
- share_value可以看成是一个可多线程并行访问的容器,可以存放各种数据,其中数据受到share_value锁的保护
- share_value要用于放在parallel对象中,提供无需跨域的高效的读写操作,share_value都应该是RO变量,用于并行访问,不然没有太大意义
- 要读写share_value前,要进行try_lock操作:try_lock(sv)
- try_lock也支持只读访问形式:try_lock(read : sv) ,这样可以多个线程并行处理,其底层实现是使用读写锁,但是这种读锁的方式只能使用有限的一些读方法,比如fetch_value,get等,不能使用如put_value,set这样的写方法
- try_lock支持传入数组,一次性try_lock多个值
注意
请注意share_value的性能问题
并不是在任何时候,share_value都能带来性能提升,它的put_value和fetch_value,每次都会深拷贝整个数据,如果其中存放的是个非常大的map或者array,会有巨大的性能开销
用法示例
// 基础用法
#pragma parallel
readonly handle sv := share_value.allocate("unnamed", 0);
// co1
void add_value() // 使用share_value之前必须要try_lock()
{
try_lock(sv)
{
mixed val = sv.fetch_value();
sv.put_value(++val);
}
}
// co2
void sub_value() // 使用share_value之前必须要try_lock()
{
try_lock(sv)
{
mixed val = sv.fetch_value();
sv.put_value(--val);
}
}
// 读写锁用法
#pragma parallel
readonly share_value sv := share_value.allocate("sv", {});
// 读可以并行
mixed query(mixed k)
{
try_lock(read : sv)
{
return sv.get(k);
}
}
// 写不能并行
void write(mixed k, mixed v)
{
try_lock(sv)
{
sv.set(k, v);
}
}
// 一次try_lock多个变量的示例
#pragma parallel
readonly share_value s1 := share_value.allocate("s1", {});
readonly share_value s2 := share_value.allocate("s2", {});
readonly share_value s3 := share_value.allocate("s3", {});
void foo1(mixed v1, mixed v2, mixed v3)
{
// 同时锁3个share value 的第一种方式
try_lock([s1, s2, s3])
{
s1.put_value(v1);
s2.put_value(v2);
s3.put_value(v3);
}
// 同时锁3个share value的第二种方式
try_lock(s1, s2, s3)
{
s1.put_value(v1);
s2.put_value(v2);
s3.put_value(v3);
}
}
share_value常用的外部函数
下面列出share_value类型一些常用的外部函数以及用法。
1. 创建share_value
函数原型:
handle share_value.allocate(string name, mixed val, int share_lock_level = 100)
使用方法:
handle sv = share_value.allocate("unnamed", [1, "hello", nil]);
2. 获取share_value的值
函数原型:
mixed share_value_instance.fetch_value(handle id)
使用方法:
mixed val = sv.fetch_value(); // val = [1, "hello", nil]
3. share_value大小
函数原型:
int share_value_instance.length(handle id, array? path = nil)
使用方法:
int size = sv.length(); // size = 2
4. share_value类型
函数原型:
mixed share_value_instance.type(handle id, array? path = nil)
使用方法:
mixed type_name = sv.type(); // type_id = 12, (array)
5. 加法/添加元素
函数原型:
mixed share_value_instance.add(handle id, mixed val, array? path = nil)
使用方法:
mixed val = sv.add([[3]]); // val = [1, "hello", nil, [3]]
6. 减法/删除元素
函数原型:
mixed share_value_instance.sub(handle id, mixed val, array? path = nil)
使用方法:
mixed val = sv.sub(["hello"]); // val = [1, nil, [3]]
7. 清除空值
函数原型:
mixed share_value_instance.clean_up(handle id, array? path = nil)
使用方法:
mixed val = sv.clean_up(); // val = [1, [3]], 适用array/map
8. 插入元素
函数原型:
mixed share_value_instance.insert(handle id, int pos, mixed value, array? path = nil)
使用方法:
mixed val = sv.insert(1, "world"); // val = true, [1, "world",3], 适用array/buffer
9. 批量插入元素
函数原型:
mixed share_value_instance.insert_n(handle id, int pos, array value, array? path = nil)
使用方法:
mixed val = sv.insert_n(0, [1,0]); // val = true, [1, 0, 1, "world", 3]适用array
10. 删除位置元素
函数原型:
mixed share_value_instance.delete_at(handle id, int pos, int n, array? path = nil)
使用方法:
mixed val = sv.delete_at(3,1);
val = true, [1, 0, 1, 3], 适用array/buffer
11. 查找首次出现位置
函数原型:
mixed share_value_instance.find(handle id, mixed val, array? path = nil)
使用方法:
mixed index = sv.find(1); // index = 0, 适用array/buffer
12. 求子序列
函数原型:
mixed share_value_instance.get_range(handle id, int pos, int size, array? path = nil)
使用方法:
mixed val = get_range(1,2); // val = [0,1], 适用array/buffer
13. 后面添加元素
函数原型:
mixed share_value_instance.push_back(handle id, mixed value, array? path = nil)
使用方法:
mixed val = sv.push_back(2); // val = true, [0, 1, 2], 适用array/buffer
14. 后面批量添加元素
函数原型:
mixed share_value_instance.push_back_n(handle id, array value, array? path = nil)
使用方法:
mixed val = sv.push_back_n([2,4]); // val = true, [0,1,2,2,4], 适用array
15. 求下界(第一个小于等于)
函数原型:
mixed share_value_instance.lower_bound(handle id, mixed value, array? path = nil)
使用方法:
mixed val = sv.lower_bound(2); // val = 1, 适用有序int
16. 求上界(第一个大于)
函数原型:
mixed share_value_instance.upper_bound(handle id, mixed value, array? path = nil)
使用方法:
mixed val = sv.upper_bound(1); // val = 2, 适用有序int
17. 清除share_value的值
函数原型:
mixed share_value_instance.clear(handle id, array? path = nil)
使用方法:
mixed val = sv.clear(); // val = true, nil, 适用array/map/buffer
18. 设置或添加share_value的值
函数原型:
void share_value_instance.put_value(handle id, mixed val, array? path = nil)
使用方法:
sv.put_valua({1:2, "hello":3, 4:"world"}); // sv.fetch_value() = {1:2, "hello":3, 4:"world"}
19. 统计keys
函数原型:
array share_value_instance.keys(handle id, array? path = nil)
使用方法:
array keys = sv.keys(); // keys = [1, "hello", 4], 适用map
20. 统计values
函数原型:
array share_value_instance.values(handle id, array? path = nil)
使用方法:
array values = sv.values(); // values = [2, 3, "world"], 适用map
21. 获取元素
函数原型:
mixed share_value_instance.get(handle id, mixed pos_or_key, array? path = nil)
使用方法:
mixed val = sv.get("hello"); // val = 3, 适用array/map/buffer
22. 设置元素
函数原型:
mixed share_value_instance.set(handle id, int pos, mixed value, array? path = nil)
使用方法:
mixed val = sv.set(1, 2); // val = true, {1:2, "hello":2, 4:"world"}, 适用array/map/buffer
23. 根据key删除元素
函数原型:
mixed share_value_instance.delete_by_key(handle id, mixed value, array? path = nil)
使用方法:
mixed val = sv.delete_by_key(4); // val = true, {1:2, "hello":2}, 适用map
24. 根据value删除元素
函数原型:
mixed share_value_instance.delete_by_value(handle id, mixed value, array? path = nil)
使用方法:
mixed val = sv.delete_by_value(2); // val = true, {}, 适用map
25. 释放share_value空间
函数原型:
void share_value_instance.free()
使用方法:
sv.free(); // sv被回收
26. 锁定并获取值
函数原型:
void share_value_instance.lock_fetch_value()
使用方法:
sv.lock_fetch_value(); // sv中的值被取出,免try_lock
27. 锁定并设置值
函数原型:
void share_value_instance.lock_put_value(val)
使用方法:
sv.lock_put_value(5); // 设置sv的值,免try_lock