0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SILVER HAIRED LISP (自作Lisp)簡単なスレッド操作

0
Posted at

SILVER HAIRED LISP のスレッド

Java25あたりから導入されたバーチャルスレッド(軽量スレッド)を使っています。
従来のOSスレッドが数千個程度だったのに対して、バーチャルスレッドは100倍近いスレッドを作れるそうです。

簡単なスレッド操作

本Lispの仕様ですが、cl-userのパッケージでは、スレッドを短い名前で使う事が出来ません。

bt: という短い名前で使いたいので、スレッド操作用のパッケージを作ります。


(defpackage :my-thread
  (:use :cl :ext)
  ;; :local-nicknames (ローカルな別名 実際のパッケージ名)
  (:local-nicknames (:bt :BORDEAUX-THREADS))
)

my-threadの中だけで、使えるローカルニックネームを付けています。
なお、:local-nicknamesは、CLの仕様にはありませんが、SBCLのような近代的なCL実装では付いているそうです。

(in-package :my-thread)
または
(in-package "my-thread")

警告
たまに、(in-package #:my-thread) こういう書き方を見かけますが、本Lispでは#:という表記を読む事が出来ません。

テスト用の関数を定義

(defun thread-test ()
   (let ((threads '()))
      (dotimes (i 1000)
       (push (bt:make-thread
               (lambda ()  (log-info  "~A"    (bt:thread-name  (bt:current-thread))  )
                           (print (list "hello from"  i ))
                           
               )
               )
            threads))

      ;; 全部 join
      (dolist (a threads)
         (bt:thread-join a))
   )
)


関数を実行

(thread-test)

途中省略

("hello from" 997)
("hello from" 998)
("hello from" 999)
("hello from" 1000)
nil
io.github.shlisp.objects.Nil

thread-testの中で使われている、log-infoという関数は、本Lispの独自関数です。

windowsの環境で、 .\winshl.cmd で、本インタープリタを起動した際、2つの窓が開くと思いますが
片方の窓は、ログを表示しています。

16:57:12.507 [lisp-make-thread-992] I i.g.s.f.LogInfoFn - lisp-make-thread-992
16:57:12.507 [lisp-make-thread-993] I i.g.s.f.LogInfoFn - lisp-make-thread-993
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1057, name = lisp-make-thread-994
16:57:12.507 [lisp-make-thread-994] I i.g.s.f.LogInfoFn - lisp-make-thread-994
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1058, name = lisp-make-thread-995
16:57:12.507 [lisp-make-thread-995] I i.g.s.f.LogInfoFn - lisp-make-thread-995
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1059, name = lisp-make-thread-996
16:57:12.507 [lisp-make-thread-996] I i.g.s.f.LogInfoFn - lisp-make-thread-996
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1060, name = lisp-make-thread-997
16:57:12.507 [lisp-make-thread-997] I i.g.s.f.LogInfoFn - lisp-make-thread-997
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1061, name = lisp-make-thread-998
16:57:12.507 [lisp-make-thread-998] I i.g.s.f.LogInfoFn - lisp-make-thread-998
16:57:12.507 [lisp-service-1] I i.g.s.l.MakeThreadFun - VirtuslThread start : id = 1062, name = lisp-make-thread-999
16:57:12.507 [lisp-make-thread-999] I i.g.s.f.LogInfoFn - lisp-make-thread-999


時刻の次に表示されている [lisp-make-thread-XXX] の部分がスレッド名です。
ログを見ると実際に1000作成されている事が確かめられます。

Javaのバーチャルスレッド(軽量スレッド)は、本当に軽いので1000個のスレッド作成をインタープリタで実行しても一瞬で終わってしまいます。

Java25以降あたりから、新規にスレッドのプログラムを作る際は、バーチャルスレッドが推奨されています。
そのため、本Lispでは、バーチャルスレッドのみを扱う事にしました。
大抵のユースケースでは、バーチャルスレッドの方が優れています。

従来の スレッド(OSスレッド)の方が優れている事も、たまにあるそうです。

WebサーバーのようなIO待ちが大量に発生するケースや、HTTPクライアントのように待ちが発生するケースではスレッドを使った方が良いそうです。
CPUバウンダリーな処理の場合、スレッドにしても、速くならないそうです。

画面に表示された ("hello from" 1000)の部分が、キレイに1から1000まで並んでいない事があります。
これは上記のテストプログラムを動かした場合の仕様だそうです。SBCLで実行した場合もキレイに1から1000まで並ばないとAIに教えてもらいました。

感想

「従来のOSスレッドでは、スレッドプールを作って、キューにためて、順次処理する」といった手法が必要で、コーディングもなかなか大変でした。

バーチャルスレッド(軽量スレッド)では、 『 スレッドプールを作る必要すらありません 』 。

スレッドは【気軽に作っては捨て】の、使い捨ての時代になりました!

さすがJavaです。Java25最高です!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?