I test this code in https://crystal-lang.org/reference/guides/concurrency.html
i = 0
while i < 10
spawn do
puts(i)
end
i += 1
end
Fiber.yield
the document say The above program prints "10" ten times
, but I got this:
2
3
10
10
10
10
10
10
10
10
$crystal --version
Crystal 0.31.1 [0e2e1d067] (2019-09-30)
LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu
$cat /etc/centos-release
CentOS Linux release 7.7.1908 (Core) ## 64bit
That’s very unexpected. Does it repeat in exactly the same manner?
My first guess would be that the -Dpreview_mt
flag is on. But in that case it might not even print 10 numbers because the main fiber exits before all of the others have executed.
The example needs to be changed anyway, because the scheduler does not guarantee an execution order for fibers, but the example expects the main fiber to be resumed only after all other fibers have been executed.
1 Like
For me it prints “10” all the time.
Regardless of this, the idea of the explanation is to make it clear that i
is just a single variable that will be shared across all spawn
invocations and you can’t rely on it being 1, 2, etc., for each spawn. The docs are overspecifying what happens: it could be what you saw or it could be all 10. Maybe that should be made clear in the docs.
1 Like
yes, I forget to say I add -Dpreview_mt
when build,
$cat test.cr
i = 0
while i < 10
spawn do
puts(i)
end
i += 1
end
Fiber.yield
$crystal build test.cr --release -Dpreview_mt
$export CRYSTAL_WORKERS=2;./test
4
6
6
7
10
10
10
10
10
10
$export CRYSTAL_WORKERS=1;./test
10
10
10
10
10
10
10
10
10
10
With CRYSTAL_WORKERS > 1 this is totally expected.
We’ll eventually need to review and update documentation for changes introduced by multithreading. But currently, it’s only a preview feature and not stable. So there’s no point in acting right now.
2 Likes