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.
handle share_value.allocate(string name, mixed val, int share_lock_level = 100)
创建share_value
2.
mixed share_value_instance.fetch_value(handle id)
获取share_value的值
3.
int share_value_instance.length(handle id, array? path = nil)
share_value大小
4.
mixed share_value_instance.type(handle id, array? path = nil)
share_value类型
5.
mixed share_value_instance.add(handle id, mixed val, array? path = nil)
加法/添加元素
6.
mixed share_value_instance.sub(handle id, mixed val, array? path = nil)
减法/删除元素
7.
mixed share_value_instance.clean_up(handle id, array? path = nil)
清除空值
8.
mixed share_value_instance.insert(handle id, int pos, mixed value, array? path = nil)
插入元素
9.
mixed share_value_instance.insert_n(handle id, int pos, array value, array? path = nil)
批量插入元素
10.
mixed share_value_instance.delete_at(handle id, int pos, int n, array? path = nil)
删除位置元素
11.
mixed share_value_instance.find(handle id, mixed val, array? path = nil)
查找首次出现位置
12.
mixed share_value_instance.get_range(handle id, int pos, int size, array? path = nil)
求子序列
13.
mixed share_value_instance.push_back(handle id, mixed value, array? path = nil)
后面添加元素
14.
mixed share_value_instance.push_back_n(handle id, array value, array? path = nil)
后面批量添加元素
15.
mixed share_value_instance.lower_bound(handle id, mixed value, array? path = nil)
求下界(第一个小于等于)
16.
mixed share_value_instance.upper_bound(handle id, mixed value, array? path = nil)
求上界(第一个大于)
17.
mixed share_value_instance.clear(handle id, array? path = nil)
清除share_value的值
18.
void share_value_instance.put_value(handle id, mixed val, array? path = nil)
设置或添加share_value的值
19.
array share_value_instance.keys(handle id, array? path = nil)
统计keys
20.
array share_value_instance.values(handle id, array? path = nil)
统计values
21.
mixed share_value_instance.get(handle id, mixed pos_or_key, array? path = nil)
获取元素
22.
mixed share_value_instance.set(handle id, int pos, mixed value, array? path = nil)
设置元素
23.
mixed share_value_instance.delete_by_key(handle id, mixed value, array? path = nil)
根据key删除元素
24.
mixed share_value_instance.delete_by_value(handle id, mixed value, array? path = nil)
根据value删除元素
25.
void share_value_instance.free()
释放share_value空间
26.
void share_value_instance.lock_fetch_value()
锁定并获取值
27.
void share_value_instance.lock_put_value(val)
锁定并设置值