Hello,
I just started working with ABCL's (version 0.26.1) threading functionality and had two questions along those lines:
1. Is there documentation for the threading support somewhere? Even a list of applicable methods and which src files they are defined in would be useful. I already found threads.lisp and abcl's swank interface. I was wondering if there were conditional-variables or conditional-waits, and was just interested in seeing what other functionality is currently supported.
2. This question is a little more complicated, and deals with when (format t "text") will print to std-out/repl and when it won't.
When I make a thread that uses (format t ...), I can see the output on the std-out/repl when I run abcl from a terminal, but not when I run it from emacs/slime. I'm guessing the reason for this is that swank doesn't redirect output from the other threads to emacs. a.) Is there a reason for not redirecting this output? i.e. will it interfere with swank's operation? b.) Is there a fix or some places I should look to see if I can write a fix?
For those interested in code, I've included some below, the following code starts two threads that send "thread1" and "thread2" messages to one mailbox. It then starts a third thread that reads from that mailbox and prints its contents. The third thread's output can be seen if this code is loaded from a terminal/prompt, but not within slime.
- Thank you.
============================================================
(in-package #:cl-user)
(defun mailbox-send (mailbox item) "Sends an item into the mailbox, notifying 1 waiter to wake up for retrieval of that object. Copied and fixed from threads.lisp" (threads:synchronized-on mailbox (setf (threads::mailbox-queue mailbox) (nconc (threads::mailbox-queue mailbox) `(,item))) (threads:object-notify mailbox)))
(defun mailbox-read (mailbox &key (blocking t)) "Blocks on the mailbox until an item is available for reading. When an item is available, it is returned." (threads:synchronized-on mailbox (when blocking (loop (unless (threads:mailbox-empty-p mailbox) (return)) (threads:object-wait mailbox))) (if (threads:mailbox-empty-p mailbox) (values nil nil) (values (pop (threads::mailbox-queue mailbox)) t)) ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; THREAD TEST
(defparameter *mailbox* (threads:make-mailbox)) (defvar *stop-mailbox* (threads:make-mailbox))
(defun send-stop () (mailbox-send *stop-mailbox* :stop))
(defun read-stop () (eq (threads:mailbox-peek *stop-mailbox*) :stop))
(defun clear-stop () (threads:synchronized-on *stop-mailbox* (setf (threads::mailbox-queue *stop-mailbox*) '())))
(defun tfn1 () (loop (when (read-stop) (return)) (mailbox-send *mailbox* (format nil "thread1")) (sleep 1)))
(defun tfn2 () (loop (when (read-stop) (return)) (mailbox-send *mailbox* (format nil "thread2")) (sleep 1)))
(defun tprint-mailbox () (loop (when (read-stop) (return)) (format t "~s~%" (mailbox-read *mailbox*))))
(defparameter *thread1* (threads:make-thread #'tfn1)) (defparameter *thread2* (threads:make-thread #'tfn2)) (defparameter *thread3* (threads:make-thread #'tprint-mailbox))