Rust始めました

なかなか初めて学ぶ言語は楽しいですね、エラーを見るのは辛いですが…

試しに、 Rustプログラミング入門 のご本に掲載されているスレッドプログラミングを動かしてみました

use std::thread;

fn main() {
    let mut handles = Vec::new();

    for x in 1..1000 {
        handles.push(thread::spawn(move || {
            println!("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 {
        handles.push(thread::spawn(move || {
            println!("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 ()
main = do
  ts <- forM [0..100000] $ \x -> do
    async $ do
      putStrLn $ "Hello, world!: " ++ show x
  forM_ ts $ \x -> do
    putStrLn $ "Wait: " ++ (show $ asyncThreadId x)
    wait x
  putStrLn "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

はじめまして

静岡の極東の浜辺で何かをやっている人間です、基本的に季節を問わずBBQとオフロードをバイクで走るのがが大好きです、暇があれば何かを焼いているか走っています。どこかの浜で焼いている姿をみたら、gentooの話もで飲みながらしましょう...

Posted

Amazon

tags

日本酒池 広井酒店 やがら やっぱた 刺身 丸干し 東京マラソン fpm php82 servant thread spawn Rust Oracle Linux 8 microcode firmware linux openzfs zfs gitea 麒麟 真野鶴 金鶴 日本酒 docker oracle pod podman cli virtualbox VirtualBox epub mobi calibre mask lens ワンライナー php redmine Linux Oracle Map OMap omap map BBQ カテゴリ管理 カテゴリ timestamp date oracle database string 麦焼酎 ダービー process 磨き蒸留 広井酒店、日本酒 芋焼酎 焼酎 ゆるキャン 広井酒店、日本酒池 spring framework java persistent spring session session spring hdbc-odbc persistent-odbc odbc day utctime スィート レマンの森 elm初期化 elm バイク xlr80 esqueleto database xl2tpd strongswan vpn l2tp ipsec 正月 ゲーム grub nginx systemctl portage 豚骨 圧力鍋 yesod-auth-hashdb yesod-auth yesod