lisp, CLOS: добавление слота в класс блокировки
Я пытаюсь добавить новый слот в класс блокировки. Это полезно, потому что у меня много блокировок в иерархии, и если я сохраняю родительскую блокировку для каждой блокировки, становится легче обнаруживать проблемы во время отладки.
К сожалению, этого, очевидно, нельзя сделать с помощью функции sure-class. Я могу добавить слоты для "процесса, но не для" блокировки, потому что он указан как встроенный в класс. Смотрите мой предыдущий вопрос здесь о том, как сделать это для 'process: lisp, CLOS: добавление слота в класс процесса
Вы знаете, как решить эту проблему? Если это невозможно, единственной альтернативой, которую я могу придумать, является сохранение иерархического отношения блокировок в хеш-таблице, но, поскольку некоторые блокировки создаются во время выполнения и в разных процессах, мне придется добавить еще одну блокировку просто чтобы получить доступ к хеш-таблице, которая хранит метаданные на замках.
Это кажется мне ужасно неэффективным. У тебя есть идея получше?
редактировать: для пояснения, я использую Clozure Common Lisp.
2 ответа
Вы можете указать метакласс, используя :metaclass
опция класса в форме defclass.
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-lock
реализован в l0-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.
В дополнение к предложению Райнера Йосвига в комментарии к этому ответу, что вы даете знать разработчикам CCL, что вы бы оценили блокировки как объекты CLOS, вы всегда можете использовать некоторую агрегацию и определить свои собственные hierarchical-lock
у которого есть слот для его примитивной блокировки и слот для родителя. С помощью магии обобщенных функций вы можете реализовать методы в обобщенных функциях, которые работают с блокировками, чтобы ваши hierarchical-lock
ведет себя как встроенный замок. (Это предполагает, что API блокировки определен в терминах общих функций.)
Вы можете использовать подкласс, который имеет такой слот.
(defclass hierarchical-lock (lock)
((parent :initarg :parent :reader parent)))