4

ロック クラスに新しいスロットを追加しようとしています。階層内に多数のロックがあり、すべてのロックの親ロックを保存すると、デバッグ中に問題を検出しやすくなるため、これは便利です。

残念ながら、これは ensure-class 関数では実行できないようです。組み込みクラスとしてリストされているため、スロットを「プロセス」に追加できますが、「ロック」には追加できません。「プロセス: lisp、CLOS:プロセスクラスにスロットを追加する方法については、私の以前の質問を参照してください。

この問題を解決する方法を知っていますか? それが不可能な場合、考えられる唯一の代替手段は、ロックの階層関係をハッシュ テーブルに保存することですが、一部のロックは実行時および異なるプロセスで作成されるため、さらに別のロックを追加する必要があります。ロックのメタデータを格納するハッシュテーブルにアクセスします。

これは非常に非効率的だと思います。もっと良いアイデアはありますか?

編集:明確にするために、私はClozure Common Lispを使用しています。

4

2 に答える 2

3

:metaclassdefclass 形式で class オプションを使用して、メタクラスを指定できます。

CL-USER> (defclass hierarchical-lock (lock)
           ((parent :initarg :parent :reader parent))
           (:metaclass built-in-class))
#<BUILT-IN-CLASS HIERARCHICAL-LOCK>

ただし、それを実行してクラスを取得することはできますが、それをインスタンス化する方法がわかりません。使用しようとするとmake-instance失敗します:

CL-USER> (make-instance 'hierarchical-lock)

; There is no applicable method for the generic function:
;   #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE #x30200002676F>
; when called with arguments:
;   (#<BUILT-IN-CLASS HIERARCHICAL-LOCK>)
;    [Condition of type SIMPLE-ERROR]

make-lockl0-aprims.lisp で次のように実装されています。

(defun make-lock (&optional name)
  "Create and return a lock object, which can be used for synchronization
between threads."
  (%make-lock (%make-recursive-lock-ptr) name))

%make-lock低レベルの実装の詳細に到達するまでの実装を追跡し続けることができますが、典型的な CLOS インスタンスと同じ方法でロックが取得されないことは明らかです。

この回答に対するコメントでの Rainer Joswig の提案に加えて、CCL 開発者に、ロックが CLOS オブジェクトであることに感謝することを知らせるように、いつでもいくつかの集約を使用hierarchical-lockして、プリミティブ ロック用のスロットと親用のスロットを持つ独自のスロットを定義できます。 . ジェネリック関数の魔法により、ロックを操作するメソッドをジェネリック関数に実装してhierarchical-lock、組み込みのロックのように動作させることができます。(これは、ロック API が汎用関数に関して定義されていることを前提としています。)

于 2013-06-15T19:49:41.003 に答える