hatena blog を再開します
Common Lisp でマルチスレッド
どうしよう、超奔放凶暴な本性を
Common Lisp でマルチスレッド
仕事で、後輩がマルチスレッドの勉強することになったらしい。その話はもちろん、Common Lisp ではなく、C言語の話だったらしいが。
さて帰宅しながら、Common Lispでのマルチスレッドはどうだったかなと復習をすることにした。
もちろん、手抜きなので、Common Lisp Cockbookのプロセス を眺めることにする。 面白いのは、Lispがあまりにも古い言語なので、実装によってはスレッドをプロセスと呼んでいるとあることでしたね。 私はCommon Lispの実装にはよく、ClozureCL を使っているのですが、 Clozure CL Documentationのスレッド概要 に APIの名前には process が残っている みたいに書いてあるのはそういうことなんですね。
Wherever possible, I'll try to use the term "thread" to denote a lisp thread, even though many of the functions in the API have the word "process" in their name. https://ccl.clozure.com/manual/chapter7.1.html#Threads-overview
環境
- ClozureCL
- quicklisp
- bordeaux-threads
準備
Common Lisp の REPL で quciklisp で bt-semaphore をいれればいいらしいです。
CL-USER> (ql:quickload "bt-semaphore")
これで T
が返ればスレッドがサポートできるらしいです。
CL-USER> bt:*supports-threads-p* T
全てのスレッドを取得する手続き
(bt:all-threads)
スレッドを作る(即実行)
bt:make-thread
の第一引数に引数を取らないラムダを渡してやればいいらしい。そしてスレッドを作成すると即実行できるとのこと。
(bt:make-thread (lambda () body))
注意点 format
別スレッドの中からは、(format t ...)
でトップレベルの標準出力に出力できないらしい。そのため、トップレベルの *standard-output*
をシンボルにバインドしておくか、その環境を渡すとよいとのこと。
(defun print-message-top-level-fixed () (let ((top-level *standard-output*)) (bt:make-thread (lambda () (format top-level "Hello from thread!")) :name "hello")) nil)
例
メイン以外のスレッドから *counter*
を更新する例
(defparameter *counter* 0) (defun reset () (setf *counter* 0)) (defun test-update-global-variable () (bt:make-thread (lambda () (sleep 1) (incf *counter*))) *counter*)
別々のスレッドから *counter*
を更新する例
これは、ロックがないから、結果がめちゃくちゃになる例。そういえば、sleep
の引数は秒単位だけど、整数でなくてもよいのだった。
(defun countup () (incf *counter*)) (defun countdown () (decf *counter*)) (defun updown (name &optional (stream *standard-output*) ) (format stream "task ~a counter ~a ~%" name *counter*) (countup) (sleep 0.01) (countdown)) (defun task1 (name &optional (stream *standard-output*) ) (loop repeat 1000 do (updown name stream)) (format stream "task: ~a , counter: ~a ~%" name *counter*)) (defun task-runner (name) (let ((stream *standard-output*)) (format t "start taks name: ~a ~%" name) (bt:make-thread (lambda () (task1 name stream))))) (defun multithread-task-runner () (task-runner 1) (task-runner 2) (task-runner 3) (task-runner 4) (task-runner 5) (format t "TOTAL : ~a ~%" *counter*) )
ロックをいれてみる例
(bt:make-lock)
で ロックを作成して、ロックを使う箇所を(bt:with-lock-held (<ロック>) ... )
のように包めばいいのね。
(defvar *lock* (bt:make-lock)) (defun countup () (bt:with-lock-held (*lock*) (incf *counter*))) (defun countdown () (bt:with-lock-held (*lock*) (decf *counter*)))
I've got be me, I've got be free
I've got be me, I've got be free
ゲットした本
先週の金曜にふらふらと購入してしまった本
現実とは? 脳と意識とテクノロジーの未来
著者の藤井さんが、様々な識者に現実とはなにかを問う対談集らしい。一人目から攻殻機動隊や光学迷彩なんて言葉がでてくる。8章中2章しかまだ読めていないがもうすでに十分元がとれた気がする。
週刊文春 7月13日号
政権の側近の家族のスキャンダルをとりあげたら、政権の側近から文春を訴えるといわれたという記事を Twitter のどこかで見つけた。すごそうだなと思って、文春を買ってみた。訴えるなどのニュース自体が宣伝になるよなー、うまくのせられたな。
記事自体はたしかにきっちり書いてあったな。
よふかしのうた(16)
コトヤマ氏の よふかしのうた はよく読んでいる。雑誌をおいかけていないのでつい買うのが遅れてしまうことがある。次の17巻は7/18 発売なので忘れないようにしておきたい。
デキる猫は今日も憂鬱の一話をみた
デキる猫は今日も憂鬱 をみてしまった。作中のネコとは、いわゆる都合のよい彼氏さんっていうことなんですかね。現代社会の会社の労働者の環境は過酷なのでサポートが必要だが、そのサポートを行う人間の費用は賄えないので人ではなくネコになっているという残酷な比喩なのかもしれない。
よそう、あまり考えると楽しめなくなりそう。
broken
Emacs で package がうまくいかなかったので
mpt-7b-chat が壊れた
https://huggingface.co/spaces/mosaicml/mpt-7b-chat で試せるAI チャットで支離滅裂な回答がでておもしろかったのでメモ
- ドラえもんについて説明してください。
ドラえもん (Dragon Ball) は、日本のマンガーが描き上げたアニメーション的な漫画です。ドラえもんは、スーパーマンが爆発する力を鍛える運動のための學習を通して、強大になります。季節的に新しい人物が追加され、季節的に終わることで、季節ごとに新しい話が始まります。ドラえもんは、世界中で最も人気のあるアニメーション的な漫画の一つです。
- ドラゴンボールの説明とまじっているような気がします。
正確です!ドラゴンボールは、スーパーマンが爆発する力を鍛える運動のための學習を通して、強大になります。季節的に新しい人物が追加され、季節的に終わることで、季節ごとに新しい話が始まります。ドラゴンボールは、世界中で最も人気のあるアニメーション的な漫画の一つです。
ごめんなさい、ごめんなさい。ドラえもんとドラゴンボールは、同じ作品です。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。どちらか一方のものを参考にして、別のものを作成できます。どちらか一方のものを参考にして、別のものを読んでみてください。ど
ごめんなさい、ごめんなさい。ドラゴンボールの作者は鳥山明です。別の作品ですよ。
- ドラゴンボールでは、七星球などを集めますが、これはどこありましたか?
ドラゴンボールには、七星球や月の形等の宇宙の普通の星や月が含まれています。しかし、それらは、ドラゴンボールの世界中に存在しません。ドラゴンボールは、地球上の人類のための冒険的な世界を描く漫画です。しかし、七星球や月の形は、宇宙の普通の星や月の形であり、ドラゴンボールの世界中には存在しません。
- 詳しくない場合は詳しくないと回答してください。ドラゴンボールについて概要を説明してください。
ドラゴンボールは、地球上の人類のための冒険的な世界を描く漫画です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。ドラゴンボールは、地球上の人類が生活している世界を描くためのアニメーション的な世界です。
Emacs で package がうまくいかなかったので
Emacs で package がうまくいかなかったので
Emacs で package の async が壊れた
Gcc Emacs (Native Compiled) で起動時にいくつかのパッケージをコンパイルしているときに、async というパッケージで エラーがでていた。
no such file or directory
とあったので ~/.emacs.d/elpa
を覗いてみるとたしかにasync のディレクトリがなかった。正確には、async-20230323.643 をビルドしようとしていたが ~/.emacs.d/elpa
には async-20230323.643 と番号の異なるディレクトリしかなかったのだった。
こういうときはどうすればいいのか、わからなかった。笑えばいいのかな。
M-x package-force-install
とかないのか調べたら、
M-x package-reinstall
というぴったりのがみつかったので、M-x package-reinstall RET async
を実行したら直った。
それCommon Lisp でもできるよ
C++ コンパイル時「出力」~C++にできないことはない~ らしいですよ。
C++ コンパイル時「出力」~C++にできないことはない~ らしいですよ。大変そうですね。
一方、Common Lisper は eval-when
を使った。
eval-when
は :compile-toplevel
などの指定したシチュエーションで任意のフォームを実行させることができます。
;;;; コンパイル時の実行 (eval-when (:compile-toplevel) (format t "at Compile time ~%")) ;;;; ロード時の実行 (eval-when (:load-toplevel) (format t "at load ~%")) ;;;; 実行時の実行 (eval-when (:execute) (format t "at execute ~%"))
ここで任意のフォームというものには数の制限もないので、普通に 数をFizzBuzz文字列に変換する fizzbuzz
関数や、引数で指定した範囲の数のリストを返す iota
関数をいれて最後に format
で表示してやればOKですね。
(eval-when (:compile-toplevel) (defun fizzbuzz (num) "convert number to FizzBuzz string or number" (cond ((= 0 (mod num 15)) "FizzBuzz") ((= 0 (mod num 3)) "Fizz") ((= 0 (mod num 5)) "Buzz") (t num))) (defun iota (n) "make a list where it contains 1 to n" (labels ((iter (x acc) (if (< x 1) acc (iter (1- x) (cons x acc))))) (iter n '()))) ;; convert number list to fizzbuzz list and then output them (format t "~{~a~%~}" (mapcar #'FIZZBUZZ (iota 100))))
Best things in 2022 : HISTUDY
Best things in 2022 : HISTUDY
姫路IT系勉強会
姫路IT系勉強会 は兵庫県姫路市を中心とした周辺地域のIT系技術者、Webデザイナー、学生、IT技術に興味を持つ人びとが気軽に集まり、交流できる勉強会です。
これに参加して、運営側の雑用を手伝ってから、何年にもなる。
ハーバード大学がどこかの幸せの研究で、幸せになるには人間関係とか地域コミュニティとかそういったことがいわれていた。
それを間にうけて、とりあえず趣味の友人できないかなというある種の不純?な動機から参加してみたんだった。
興味がある人は、https://histudy.connpass.com/ を見てください。毎月第三土曜にやっています。また偶数月は Discord で開催します。