跳到主要内容
版本:release

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