Prev: Loop syntax style
Next: NoSQL Movement?
From: Peter Keller on 3 Mar 2010 13:49 Hello, I'm using SBCL 1.0.33.30 and the Bordeaux Thread package. My question is in this piece of code: (unwind-protect (while t ;; set up some data (push (make-thread #'work-func) *thread-list)) ; cleanup of uw-p (mapc #'(lamdba (thr) (when (thread-alive-p thr) (destroy-thread thr))))) I see two possibilities for race conditions: 1. If the make-thread completes, and before the push happens, the form stops evaluation through condition (how it would get signaled there I don't know) or breaking into the debugger and going back to the top level (which I was unlucky enough to actually perform by hand). 2. The thread completes after thread-alive-p states it was alive but before destroy-thread evaluates. For number 2, I chose to solve the problem of the signaled condition by destroy-thread with (ignore-errors ...), but I have no idea how to solve number 1. As far as I can tell a thread could be failed to be cleaned up under the right circumstances and left running. Are there any idiomatic ways to deal with this problem? I want to ensure that if the program I'm running is forced to quit, all threads are cleaned up. Thank you. -pete
From: vanekl on 3 Mar 2010 14:48 On Mar 3, 1:49 pm, Peter Keller <psil...(a)merlin.cs.wisc.edu> wrote: > Hello, > > I'm using SBCL 1.0.33.30 and the Bordeaux Thread package. My question is in > this piece of code: > > (unwind-protect > (while t > ;; set up some data > (push > (make-thread #'work-func) > *thread-list)) > > ; cleanup of uw-p > (mapc #'(lamdba (thr) > (when (thread-alive-p thr) > (destroy-thread thr))))) > > I see two possibilities for race conditions: > > 1. If the make-thread completes, and before the push happens, the form > stops evaluation through condition (how it would get signaled there I > don't know) or breaking into the debugger and going back to the top level > (which I was unlucky enough to actually perform by hand). > > 2. The thread completes after thread-alive-p states it was alive but before > destroy-thread evaluates. > > For number 2, I chose to solve the problem of the signaled condition by > destroy-thread with (ignore-errors ...), but I have no idea how to solve > number 1. As far as I can tell a thread could be failed to be cleaned > up under the right circumstances and left running. > > Are there any idiomatic ways to deal with this problem? I want to ensure that > if the program I'm running is forced to quit, all threads are cleaned up. > > Thank you. > > -pete (use-package :sb-thread) (defun kill-my-thread (tgt-thread-name) (map nil (lambda (thread) (let ((name (thread-name thread))) (if (equalp tgt-thread-name name) (progn (format t "killing thread ~s~%" name) (terminate-thread thread)) (format t "alive: ~a~%" name)))) (list-all-threads))) (progn (terpri) (let ((s *standard-output*)) (make-thread (lambda () (format s "~%Kill me!~%") (force-output) (sleep 10)) :name "test-thread")) (kill-my-thread "test-thread"))
From: Peter Keller on 3 Mar 2010 15:22 vanekl <vanek(a)acd.net> wrote: > On Mar 3, 1:49?pm, Peter Keller <psil...(a)merlin.cs.wisc.edu> wrote: [ I mention a couple race conditions in the below code ] [ this code below is adjusted, it had a stupid typo in it] >> (unwind-protect >> (while t >> ;; set up some data >> (push >> (make-thread #'work-func) >> *thread-list*)) >> >> ; cleanup of uw-p >> (mapc #'(lamdba (thr) >> (when (thread-alive-p thr) >> (destroy-thread thr))) >> *thread-list*)) >> Are there any idiomatic ways to deal with this problem? I want to ensure that >> if the program I'm running is forced to quit, all threads are cleaned up. > (use-package :sb-thread) > > (defun kill-my-thread (tgt-thread-name) > (map nil > (lambda (thread) > (let ((name (thread-name thread))) > (if (equalp tgt-thread-name name) > (progn > (format t "killing thread ~s~%" name) > (terminate-thread thread)) > (format t "alive: ~a~%" name)))) > (list-all-threads))) > > (progn > (terpri) > (let ((s *standard-output*)) > (make-thread (lambda () > (format s "~%Kill me!~%") > (force-output) > (sleep 10)) > :name "test-thread")) > (kill-my-thread "test-thread")) So the idiomatic method you suggest is I should use bordeaux threads' (all-threads) to enumerate the threads instead of keeping the thread list manually? This is in the hopes that the list returned by all-threads is properly set up by bordeaux threads? Also, I'd like to keep the solution in bordaeux threads. Thank you. -pete
From: vanekl on 3 Mar 2010 15:31 On Mar 3, 3:22 pm, Peter Keller <psil...(a)merlin.cs.wisc.edu> wrote: > vanekl <va...(a)acd.net> wrote: > > On Mar 3, 1:49?pm, Peter Keller <psil...(a)merlin.cs.wisc.edu> wrote: > > [ I mention a couple race conditions in the below code ] > > [ this code below is adjusted, it had a stupid typo in it] > > > > >> (unwind-protect > >> (while t > >> ;; set up some data > >> (push > >> (make-thread #'work-func) > >> *thread-list*)) > > >> ; cleanup of uw-p > >> (mapc #'(lamdba (thr) > >> (when (thread-alive-p thr) > >> (destroy-thread thr))) > >> *thread-list*)) > >> Are there any idiomatic ways to deal with this problem? I want to ensure that > >> if the program I'm running is forced to quit, all threads are cleaned up. > > (use-package :sb-thread) > > > (defun kill-my-thread (tgt-thread-name) > > (map nil > > (lambda (thread) > > (let ((name (thread-name thread))) > > (if (equalp tgt-thread-name name) > > (progn > > (format t "killing thread ~s~%" name) > > (terminate-thread thread)) > > (format t "alive: ~a~%" name)))) > > (list-all-threads))) > > > (progn > > (terpri) > > (let ((s *standard-output*)) > > (make-thread (lambda () > > (format s "~%Kill me!~%") > > (force-output) > > (sleep 10)) > > :name "test-thread")) > > (kill-my-thread "test-thread")) > > So the idiomatic method you suggest is I should use bordeaux threads' > (all-threads) to enumerate the threads instead of keeping the thread list > manually? This is in the hopes that the list returned by all-threads is > properly set up by bordeaux threads? Also, I'd like to keep the solution > in bordaeux threads. > > Thank you. > > -pete Yes, if you are worried about zombie threads and another package is already managing live threads, I would rely upon that package instead of duplicating effort (and possibly introducing errors).
From: Peter Keller on 3 Mar 2010 16:17 vanekl <vanek(a)acd.net> wrote: > On Mar 3, 3:22?pm, Peter Keller <psil...(a)merlin.cs.wisc.edu> wrote: >> So the idiomatic method you suggest is I should use bordeaux threads' >> (all-threads) to enumerate the threads instead of keeping the thread list >> manually? This is in the hopes that the list returned by all-threads is >> properly set up by bordeaux threads? Also, I'd like to keep the solution >> in bordaeux threads. >> > Yes, if you are worried about zombie threads and another package is > already managing live threads, I would rely upon that package instead > of duplicating effort (and possibly introducing errors). Good point. Thank you! -pete
|
Pages: 1 Prev: Loop syntax style Next: NoSQL Movement? |