From: Helmut E. <e96...@st...> - 2004-02-04 22:34:18
|
[ Apologies if you receive multiple copies of this message. ] Hi, I'd like to implement a simple mechanism to pass message between threads, but I don't quite understand how condition variables are supposed to be used. My code looks much like the example below. There is a global mutex and a global waitqueue. I create one thread that reads all messages out from the message queue and prints them to stdout and the main thread sends messages to the other thread in a endless loop. This seems to work for a while (the counter goes sometimes up to one million), but then SBCL just hangs and even C-c-ing has no effect. Is there a bug in my code? in SBCL? Should I write this differently? It's also bit strange that "New thread: xxx" is printed two times. Are streams not thread safe by default? All this happens with SBCL 0.8.7.36, Linux 2.4.12, glibc 2.2.2. (defpackage :sb-ipc-test (:use :cl)) (in-package :sb-ipc-test) (defvar *mutex* (sb-thread:make-mutex)) (defvar *waitqueue* (sb-thread:make-waitqueue)) (defvar *message-queue* (list)) (defun receive () (sb-thread:with-mutex (*mutex*) (loop (cond (*message-queue* (return (pop *message-queue*))) (t (sb-thread:condition-wait *waitqueue* *mutex*)))))) (defun send (message) (sb-thread:with-mutex (*mutex*) (setf *message-queue* (nconc *message-queue* (list message))) (sb-thread:condition-notify *waitqueue*))) (defun receive-loop () (let ((i 0)) (loop (force-output) (let ((message (receive))) (format t "received: ~S " message) (ecase message (:print (format t "~D~%" (incf i))) (:stop (terpri) (return))))))) (defun test () (let ((thread (sb-thread:make-thread #'receive-loop))) (format t "New thread: ~S~%" thread) (loop (send :print)))) (test) |