Rust始めました
なかなか初めて学ぶ言語は楽しいですね、エラーを見るのは辛いですが…
試しに、 Rustプログラミング入門 のご本に掲載されているスレッドプログラミングを動かしてみました
use std::thread;
fn main() {
let mut handles = Vec::new();
for x in 1..1000 {
.push(thread::spawn(move || {
handlesprintln!("Hello, world!: {}", x);
}));
}
for handle in handles {
let _ = handle.join();
}
}
実行してみる
$ cargo run
...
Hello, world!: 995
Hello, world!: 996
Hello, world!: 997
Hello, world!: 998
Hello, world!: 999
$
おお、うごいた、これで私も、Rustちょっとデキル、それならもっとスレッド増やしてみよう
fn main() {
let mut handles = Vec::new();
for x in 1..100000 {
handles.push(thread::spawn(move || {
println!("Hello, world!: {}", x);
...
スレッドを100000にして、カーゴらん
cargo run
$ Hello, world!: 1764
Hello, world!: 1765
Hello, world!: 1766
thread 'mainthread '' panicked at 'Hello, world!: 1767
<unnamed>failed to spawn thread: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }' panicked at '', failed to set up alternative stack guard page: Cannot allocate memory (os error 12)/rustc/90743e7298aca107ddaa0c202a4d3604e29bfeb6/library/std/src/thread/mod.rs', :thread 'library/std/src/sys/unix/stack_overflow.rs708:<unnamed>:144' panicked at '29:failed to allocate an alternative stack: Cannot allocate memory (os error 12)
13',
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
library/std/src/sys/unix/stack_overflow.rs:Hello, world!: 1768
140:13
Hello, world!: 1769
Hello, world!: 1770
Hello, world!: 1771
fatal runtime error: failed to initiate panic, error 5fatal runtime error:
failed to initiate panic, error 5
Hello, world!: 1772
Hello, world!: 1773
Hello, world!: 1774
...
おちる
library/std/src/sys/unix/stack_overflow.rs708
stack overflow ということで叱られる、なので、メインスレッドのstackを大きくしてる(コードはそのつもり…)
use std::thread;
fn thread_main() {
// 実はここがあやしいと思っているが...
let mut handles = Vec::new();
for x in 1..100000 {
.push(thread::spawn(move || {
handlesprintln!("Hello, world!: {}", x);
}));
}
for handle in handles {
let _ = handle.join();
}
}
fn main() {
// メインスレッドのstackサイズのつもり
const STACK_SIZE: usize = 256 * 1024 * 1024;
std::thread::Builder::new()
.stack_size(STACK_SIZE)
.spawn(thread_main)
.unwrap()
.join()
.unwrap();
}
これもNG、なかなかムズカシイ、実効速度が速い分、メモリまわりのとコーディングの知識が必要かな、 std::thread この辺も漁ってはみましたが、解決できずでした、解決策を誰かご存知でしょうか?
Haskell で同じようなコードを書いてみた
悔しかったので haskell で同じようなコードを書いてみた
import Control.Monad
import Control.Concurrent
import Control.Concurrent.Async
main :: IO ()
= do
main <- forM [0..100000] $ \x -> do
ts $ do
async putStrLn $ "Hello, world!: " ++ show x
$ \x -> do
forM_ ts putStrLn $ "Wait: " ++ (show $ asyncThreadId x)
wait xputStrLn "OK"
スレッドを利用できるよう、ビルドして
$ ghc -O2 Async.hs -rtsopts -threaded
そして4コア利用して実行
$ ./Async +RTS -N4
...
Wait: ThreadId 100003
Wait: ThreadId 100004
Wait: ThreadId 100005
Wait: ThreadId 100006
Wait: ThreadId 100007
Wait: ThreadId 100008
OK
$
おちない、stack使ってるかどうか不明ではありますが…
Rustの所有権とか借用とか、ムーブセマンティクス等々、新しいというか普段馴染みがないことを覚えるのはストレスがかかりますが、頑張って覚えていきたいと思っております、たのしいですが。
以上、 Rustちょっとデキルようになってみたい でした…厳しい
Posted on 2023-01-22 11:37:14