forum
forum copied to clipboard
【Zig 日报】在两个线程之间共享数据
当我们要更改线程之间共享的数据时,必须使用 Mutex(互斥标志,Mutually exclusive)来同步线程,否则结果可能出乎意料。
const std = @import("std");
const Thread = std.Thread;
const Mutex = Thread.Mutex;
const SharedData = struct {
mutex: Mutex,
value: i32,
pub fn updateValue(self: *SharedData, increment: i32) void {
// Use `tryLock` if you don't want to block
self.mutex.lock();
defer self.mutex.unlock();
for (0..100) |_| {
self.value += increment;
}
}
};
pub fn main() !void {
var shared_data = SharedData{ .mutex = Mutex{}, .value = 0 };
// This block is necessary to ensure that all threads are joined before proceeding.
{
const t1 = try Thread.spawn(.{}, SharedData.updateValue, .{ &shared_data, 1 });
defer t1.join();
const t2 = try Thread.spawn(.{}, SharedData.updateValue, .{ &shared_data, 2 });
defer t2.join();
}
try std.testing.expectEqual(shared_data.value, 300);
}
如果我们取消 Mutex 保护,结果很可能小于 300。
加入我们
Zig 中文社区是一个开放的组织,我们致力于推广 Zig 在中文群体中的使用,有多种方式可以参与进来:
注释掉那两行代码,运行了很多遍也没失败;加入 yield 才看到预期行为。
估计你电脑速度太快了,可以试试把lock 放循环里面试试
估计你电脑速度太快了,可以试试把lock 放循环里面试试
不能啊,我用的是 macmini m2 。 另外,注释掉已经不生效了,放在哪里都一样啊。
加入sleep,或者扩大循环次数。这是一个概率出现的现象,竞争,多试几次
加入sleep,或者扩大循环次数。这是一个概率出现的现象,竞争,多试几次
放大 100 倍可以了。