多线程并发访问变量的安全控制语法
语法
with shared 变量名 => 局部变量 do 语句段
with shared 变量名1 => 局部变量1, 变量名2 => 局部变量2 do 语句段
最多支持同时安全访问2个共享变量。
嵌套with shared语句的支持
可以嵌套,但是只保护当前with shared定义的变量(为了避免可能因加锁次序而导致的死锁问题)。 所以在这样的情况下,不要使用上一层定义的共享变量。
with shared a=>a do
begin
a:=100;
with shared b=>b do
begin
// 在这里不要使用a
b:=200;
println("b={}", b);
end
// 这时可以安全使用a
println("a={}", a);
end
样例
例子
// 初始化共享变量a
with shared a=>a do
a:=100;
// 启动线程1
taskgroup_run(tg, () =>
begin
res := 0;
for i:=0 to 1000 do
begin
sleep(1);
with shared a=>a do
begin
println("thread1: before a={}", a);
a++;
println("thread1: after a={}", a);
res := a;
end
end
println("thread1 exit, return {}", res);
return res;
end);
// 启动线程2
taskgroup_run(tg, () =>
begin
res := 0;
for i:=0 to 2000 do
begin
sleep(1);
with shared a=>a do
begin
println("thread2: before a={}", a);
a--;
println("thread2: after a={}", a);
res := a;
end
end
println("thread2 exit, return {}", res);
return res;
end);
// 等待所有任务结束
res := taskgroup_wait_all(tg);
println("res={}", res);
taskgroup_destroy(tg);
运行打印:
thread2: before a=100
thread2: after a=99
thread1: before a=99
thread1: after a=100
thread2: before a=100
thread2: after a=99
thread1: before a=99
thread1: after a=100
thread1: before a=100
thread1: after a=101
thread2: before a=101
thread2: after a=100
thread2: before a=100
thread2: after a=99
thread1: before a=99
thread1: after a=100
thread2: before a=100
thread2: after a=99
...
避免死锁
tg := taskgroup_create(5);
// 线程1 访问次序是先"a"后"b"
taskgroup_run(tg, () =>
begin
for i:=0 to 10000 do
begin
sleep(1);
with shared a=>a do
begin
a:=i;
println("thread1: a={}", a);
with shared b=>b do
begin
b:=i-1;
println("thread1: b={}", b);
end
end
end
end);
// 线程2 访问次序是先"b"后"a"
taskgroup_run(tg, () =>
begin
for i:=10000 to 20000 do
begin
sleep(1);
with shared b=>b do
begin
b:=i;
println("thread2: b={}", b);
with shared a=>a do
begin
a:=i-1;
println("thread2: a={}", a);
end
end
end
end);
res := taskgroup_wait_all(tg);
println("res={}", res);
taskgroup_destroy(tg);
打印:
thread1: a=0
thread2: b=10000
thread2: a=9999
thread1: b=-1
thread2: b=10001
thread1: a=1
thread1: b=0
thread2: a=10000
thread2: b=10002
thread1: a=2
thread1: b=1
thread2: a=10001
thread1: a=3
thread2: b=10003
thread2: a=10002
thread1: b=2
thread2: b=10004
...
虽然共享变量的访问次序不同,但是并没有发生死锁。