I am trying to get a set number of threads to do a process at the same time in
sbcl. There is no built-in semaphore that I found, so I created one:
(defclass semaphore ()
((semcount :initarg :count :initform 1)
(semmutex :initform (sb-thread:make-mutex))
(semqueue :initform (sb-thread:make-waitqueue))))
(defmethod Psem ((sem semaphore))
"decrease semaphore"
(with-slots (semmutex semcount semqueue) sem
(sb-thread:with-mutex (semmutex)
(loop
until (> semcount 0)
do (sb-thread:condition-wait semqueue semmutex)
finally (decf semcount)))))
(defmethod Vsem ((sem semaphore))
"increase semaphore"
(with-slots (semmutex semcount semqueue) sem
(sb-thread:with-mutex (semmutex)
(incf semcount)
(sb-thread:condition-notify semqueue))))
And start them like so:
(defun add-xml-to-db-threaded (xml query num-of-threads)
"adds images from the fetched xml to the database"
(let ((sem (make-instance 'semaphore :count num-of-threads)))
(format t "starting ~A threads...~%" num-of-threads)
(with-accessors ((images Results)) xml
(dolist (result images)
(Psem sem)
(sb-thread:make-thread
#'(lambda ()
(add-yahoo-result-to-db result query)
(Vsem sem)))))
(format t "all threads started~%")))
Using this code, I consistently get all sorts of errors:
simple-errors in other threads (but that arn't caused by
calling add-yahoo-result-to-db in a single-threaded way)
, or GC errors (destroys lisp image).
I was wondering if ya'll think that these errors are caused by
the above code, or something in add-yahoo-result-to-db. I'm scratching my
head. Trying to debug the simple-errors by (sb-thread:release-foreground)
simple invokes a set of nested errors on the other thread in the debugger,
and also kills the image.
--
-Dave Watson
········@docwatson.org