我写了下面两个例子来测试Zig和Erlang的并发性。
% Erlang
-module(spwntest).
disp()->
_ = 234.
main(_) ->
F = fun(_) -> spawn(fun() -> disp() end) end,
lists:foreach(F,lists:seq(1,2000000)),
io:format("done").
%% Result: All Erlang processes complete their work in less than 10 seconds
//!Zig
const std = @import("std");
pub fn main() !void{
for(0..100000) |_|{
const t = try std.Thread.spawn(.{},disp,.{});
t.join();
}
std.debug.print("done",.{});
}
fn disp() void{
_ = 10;
}
结果:Zig 需要花费大量时间才能让所有线程完成其工作。
根据我的理解,与 Zig 并发相比,Erlang 进程效率更高,有助于开发可扩展的应用程序。
我想听听专家的意见,以帮助我的理解。
您的 Zig 代码中没有并发性。创建每个线程后,您可以调用
join
。这使得你的代码是连续的。
此外, std.Thread.spawn
创建一个操作系统线程。而在 Erlang 中,spawn
创建了其他东西。来自维基百科:
它们既不是操作系统进程,也不是线程,而是由BEAM调度的轻量级进程。与操作系统进程一样(但与操作系统线程不同),它们彼此不共享状态。
这是更正后的代码:
const std = @import("std");
pub fn main() !void {
const count = 100000;
var threads: [count]std.Thread = undefined;
// spawning threads
for (0..count) |i| {
threads[i] = try std.Thread.spawn(.{}, disp, .{});
}
// waiting for all threads to finish
for (0..count) |i| {
threads[i].join();
}
std.debug.print("done", .{});
}
fn disp() void {
_ = 10;
}