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ちょっとデキルようになってみたい でした…厳しい
2023年 正月
2023年開始しましたが
と言ってももう1月も中盤ではございますが、改めて、あけましておめでとうございます。
気がついたら、去年は1つもブログを書いていなかったので、今年は書くこと得に無いのですが、頑張ってoutputしていきたいと思っております。
とりあえず、ネタもないので正月の出来事から
初日の出
強力粉購入
やること無いので粉で遊ぶことにしました
My Gear その1
材料ぶっこんでスイッチ一つ、私の能力は何一つ無、21世紀はすばらしい、パン、うめぇ
これは、手でねって、麺生成機でクルクル、麺、トゥル、トゥル
My Gear その2
パン焼き機、長男が餅を焼く予定が、パン焼き機を焼いてしまったので、致し方なく新調
温度設定できることに気づき、たまげる、さすが、世界の象印、万歳
My Gear その3
プリンター、Windows11ではつかえなくなったので、新調、自分のマシンがGentooであることで、つかえない
My Gear その4
女房の制止を振り切り、フロントフォークのリストア、そのたもろもろ修理、山はいりたい、だれか一緒にライディングしないか?
My Gear その5
NEXのエネルギー原をエネループへ換装、速すぎて、iPhoneのシャッター間に合わずピンボケ
My Gear その6
Rust、今年はRustを制覇しようと思う
struct Person {
name: String,
age: u32
}
impl Person {
fn new(name: &str, age: u32) -> Person {
Person {
name: String::from(name),
age: age
}
}
fn ieyo_namae(&self) -> &Self {
println!("Urusee {}", self.name);
self
}
fn toshi_oshiero(&self) -> &Self {
println!("Shiruka Bokee {}", self.age);
self
}
}
fn main() {
let p = Person::new("Jyuzou", 78);
p.ieyo_namae().toshi_oshiero();
}
Haskellがやっぱり、よいが。。。。。。
type STM :: * -> *
newtype STM a
= GHC.Conc.Sync.STM (GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
-- Defined in ‘GHC.Conc.Sync’
instance Applicative STM -- Defined in ‘GHC.Conc.Sync’
instance Functor STM -- Defined in ‘GHC.Conc.Sync’
instance Monad STM -- Defined in ‘GHC.Conc.Sync’
まとめ
ことしも、よろしくお願い致します。
VirtualBoxのホストオンリーアダプタの設定方法が変わっていた
VirtualBox-6.1.28 以降で発生
6.1.24 以降でどうもホストオンリーアダプタの設定ルールが少し変わってようで、いままで自由にIPを設定変更できていたのですがアクセス違反のエラーでできなくなっていた。
ホストネットワークインターフェースのパラメーターの保存に失敗しました。
呼び出し先 RC: E_ACCESSDENIED (0x80070005)
適当にイジってみても、治らず、しょうがないので調べることに…
Changelog
Changelog for VirtualBox 6.1 のページを調べてみた
なにやら、微妙なコメント発見、英語力は無いが、ホストオンリーアダプタの設定範囲の設定ミスを防ぐための処置を行ったような記載を発見、 ドキュメント見ないとVM動かなくなっちゃうよ! のような、ということで
ドキュメントを確認。
ホストオンリーネットワーク設定
Host-Only Networking によりますと /etc/vbox/networks.conf を作って設定しろと
On Linux, Mac OS X and Solaris Oracle VM VirtualBox will only allow IP addresses in 192.168.56.0/21 range to be assigned to host-only adapters.
For IPv6 only link-local addresses are allowed. If other ranges are desired, they can be enabled by creating /etc/vbox/networks.conf and specifying allowed ranges there.
For example, to allow 10.0.0.0/8 and 192.168.0.0/16 IPv4 ranges as well as 2001::/64 range put the following lines into /etc/vbox/networks.conf:
Linux, Mac OS, Solaris で 192.168.56.0/21 以外のアドレスで設定するには /etc/vbox/networks.conf を書いて設定しろと書いてあったので作成。
* 192.168.253.0/24 192.168.254.0/24
# * 2001::/64
その後、再設定したところ、指定したIPの範囲でホストオンリーアダプタの設定を行うことができました。 ただ、1回目の設定では設定したIPが表示上反映されていないようなので、一度ダイアログを閉じて再度開いてみてください、変更はされているようです。(これはバグでしょう)
これ、何気にハマっている人いるんじゃないかな、私は適当にやって、2時間ハマりました、やっぱりドキュメント先に確認しましょう。
老眼の悪化と電子書籍の変換
目の老化が指数関数的に悪くなっていると感じているますが、焼酎の濃度だけは進化を遂げている、ここ最近です。
よく電子書籍をスマホやタブレットで見ていたのですが、さすがにスマホで見ると文字が チャイチー のでまったく文字が見えない状況になり タブレットがない場合に不自由することが多くなってきました。
日常はKindleで読んでいるのでmobi形式のものなら文字を拡大できるので問題ないのですが、PDFになると拡大したり、ずらしたり、縮小したりと、忙しく なってしまうので、非常に読みにくく感じています。 (デバイスが チャイチー のが一番の問題なのですが…)
さらに、オライリーなどで買った本がepub形式のものだと、読みやすいのですが、Kindleにエクスポートできない モドカシサ を辱められます。
なにか良い解決方法がないかと、gentooを漁っていたところ、python製のcalibreというツールを発見したので試してみたところ便利でした。
インストール
これだけです
# emerge -pv app-text/calibre
epubからmobiへの変換
これだけです
cuomo@cmv ~/temp $ ebook-convert SRE\ サイトリライアビリティエンジニアリング.epub SRE\ サイトリライアビリティエンジニアリング.mobi
1% 入力をHTMLに変換中...
InputFormatPlugin: EPUB Input running
on /home/cuomo/temp/SRE サイトリライアビリティエンジニアリング.epub
Found HTML cover OEBPS/index.xhtml
Parsing all content...
34% 電子書籍の変換中...
...
...
Converting XHTML to Mobipocket markup...
Serializing markup content...
Compressing markup content...
Generating MOBI index for a book
MOBI output written to /home/cuomo/temp/SRE サイトリライアビリティエンジニアリング.mobi
出力を名前をつけて保存 /home/cuomo/temp/SRE サイトリライアビリティエンジニアリング.mobi
cuomo@cmv ~/temp $
PDFからmobi
これだけです、が、PDF内のサンプルコードなどはかなり読みにくいです、多少のインデントのずれは 老眼目グレップ 、経験豊富な 心の老眼目 で見れば、問題ないです。
cuomo@cmv ~/temp $ ebook-convert Real\ World\ Haskell.pdf Real\ World\ Haskell.mobi
1% 入力をHTMLに変換中...
InputFormatPlugin: PDF Input running
on /home/cuomo/temp/Real World Haskell.pdf
pdftohtml log:
Page-1
Page-2
Page-3
...
...
Page-719
Page-720
Page-721
Parsing all content...
34% 電子書籍の変換中...
Merging user specified metadata...
Detecting structure...
Flattening CSS and remapping font sizes...
Source base font size is 12.00000pt
Removing fake margins...
Cleaning up manifest...
Trimming unused files from manifest...
Creating MOBI Output...
67% プラグイン MOBI Output を実行中
Serializing resources...
Creating MOBI 6 output
Generating in-line TOC...
Applying case-transforming CSS...
Rasterizing SVG images...
Converting XHTML to Mobipocket markup...
Serializing markup content...
Compressing markup content...
Generating MOBI index for a book
MOBI output written to /home/cuomo/temp/Real World Haskell.mobi
出力を名前をつけて保存 /home/cuomo/temp/Real World Haskell.mobi
cuomo@cmv ~/temp $
少し中を覗くと calibre-server などという謎のコマンドがあったりと、色々ありそうですが、これだけ使えれば目的は達成できそうなので良とします。
Pythonには感謝です。
ビールから意識を遠ざけるための暇つぶし
Tech
>
Haskell
酒飲めずあまりに暇だったのでつまらない時間つぶし、ファイルかディレクトリか判断するだけのコード
import os
def main():
r = []
fs = os.listdir(".")
for f in fs:
r.append(os.path.isdir(f))
return r
if __name__ == '__main__':
r = main()
print(r)
Pythonはカレントディレクトリ 「.」 と 親ディレクトリ 「..」 は親切に返してこない、これはいい
これほぼ同じコードをhaskellで書いてみた
import System.Directory
import System.Posix
import Control.Monad
main :: IO ()
main = do
r <- return . map isDirectory =<< mapM getFileStatus =<< getDirectoryContents "."
putStrLn $ show r
getFileStatus で stat っぽい事してるので少し違うけど心地良い、ループがないけど最後の map でループしてて [チョメチョメ] が帰ってきて、 isDirectory の型さえ調べればもはや [Bool] これとすぐ分かる。 一番右の getDirectoryContents “.” と一番左の map isDirectory だけで真ん中はそんなに重要でなくなる。
そして、これをphpで書いてみた
<?php
$r = main();
var_dump($r);
function main() {
$d = opendir('.');
$res = array();
while (($file = readdir($d)) !== false) {
if (is_dir($file)) {
array_push($res, true);
} else {
array_push($res, false);
}
}
closedir($d);
return $res;
}
久しぶりにphp書いたけど、結構エラーで叱られる、たまには違う言語も書かないとだめですね。
ちなみにphpはワンライナーでもやれる
<?php $r = main();var_dump($r);function main() {$d = opendir('.');$res = array();while (($file = readdir($d)) !== false) {if (is_dir($file)) {array_push($res, true);} else {array_push($res, false);}}closedir($d);return $res;}
phpつおい、ちなみに私は、 ZendFramework派 です。