manpagez: man pages & more
info bigloo
Home | html | info | man
[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

17.2.2.1 Thread

Bigloo syntax: instantiate::fthread (body thunk) [(name name)]

Returns a new thread which is not started yet. The body of the thread is the body of the procedure thunk. The optional argument name can be use to identify the thread. It can be any Bigloo value.

(instantiate::fthread (body (lambda () (print 1) (thread-yield!)
(print 2)))
                      (name 'my-thread))

The former thread-start function can be rewritten as follow:

(define (make-thread body . name)
  (if (pair? name)
      (instantiate::fthread (body body) (name (car name)))
      (instantiate::fthread (body body))))
SRFI-18 function: thread-start! thread [scheduler]

Runs a thread created with make-thread. If scheduler is provided, the thread is started in this particular scheduler. Otherwise, it is started in the current scheduler (see Section Scheduler). Threads are started at the beginning of reactions (see Section Scheduler).

SRFI-18 function: thread-yield!

The current thread cooperates. That is, it is suspended for the reaction and the scheduler selects a new thread to be resumed. The scheduler resumes the next avaliable thread. If there is only one thread started in the scheduler, the same thread is resumed. A reaction corresponds to the invocation of a scheduler-react! call (see Section Scheduler).

SRFI-18 function: thread-sleep! timeout

The current thread cooperates during exactly timeout reactions (see Scheduler). It is suspended and the scheduler selects a new thread to be resumed. If there is only one thread started in the scheduler, the same thread will be resumed.

(let ((t1 (instantiate::fthread
             (body (lambda () (thread-sleep! 2) (display 'foo)))))
      (t2 (instantiate::fthread
             (body (lambda () (let loop ((n 1))
                                 (display n) 
                                 (thread-yield!)
                                 (if (< n 5)
                                 (loop (+ n 1)))))))))
   (thread-start! t1)
   (thread-start! t2)
   (scheduler-start!)) -| 12foo34
SRFI-18 function: thread-terminate! thread

Terminates thread at the end of the current reaction.

SRFI-18 function: thread-join! thread [timeout [timeout-val]]

The current thread waits until thread terminates or until timeout is reached (when supplied). If the timeout is reached, thread-join! returns timeout-val. If thread terminates, thread-join! returns the end-result of the thread or the end-exception if that thread terminates abnormally.

If several threads wait for the termination of the same thread, they are all notified of the termination during the current reaction.

(let* ((t1 (thread-start!
            (instantiate::fthread
               (body (lambda () (thread-sleep! 3) 'foo)))))
       (t2 (thread-start!
            (instantiate::fthread
               (body (lambda () (print "t1: " (thread-join! t1 1)))))))
       (t3 (thread-start!
            (instantiate::fthread
               (body (lambda () (print "t2: " (thread-join! t1 2 'bar)))))))
       (t3 (thread-start!
            (instantiate::fthread
               (body (lambda () (print "t3: " (thread-join! t1)))))))
       (t4 (thread-start!
            (instantiate::fthread
               (body (lambda () (print "t4: " (thread-join! t1))))))))
   (scheduler-start!))
   -| t1: #|%uncaught-exception [reason: (exception . join-timeout)]|
      t2: bar
      t3: foo
      t4: foo

thread-join! can be used to wait for a Posix Thread termination. The pthread object must be started with thread-start-joinable!.

Bigloo function: thread-suspend! thread
Bigloo function: thread-resume! thread

Suspends/resumes the thread at the end of reaction. While suspended a thread is not eligible to get the processor by the scheduler.

Bigloo function: thread-await! signal [timeout]

Blocks the thread until signal has been broadcast or until timeout has elapsed. The function thread-await! returns the value associated with the previous emissions of the signal that took place during the reaction.

(let ((t1 (thread-start! (instantiate::fthread
                            (body (lambda ()
                                     (display (thread-await! 'foo))
                                     (display (thread-await! 'bar)))))))
      (t2 (thread-start! (instantiate::fthread
                            (body (lambda ()
                                     (broadcast! 'foo 'val1-foo)
                                     (broadcast! 'foo 'val2-foo))))))
      (t3 (thread-start! (instantiate::fthread
                            (body (lambda ()
                                     (thread-sleep! 2)
                                     (broadcast! 'bar 'val-bar)))))))
   (let loop ((n 1))
      (display n)
      (scheduler-react! (default-scheduler))
      (loop (+ n 1))))
  -| 1val2-foo23val-bar456...

The function thread-await! cannot be used to intercept all the signals broadcast during a reaction. This is illustrated by the following example where obviously thread-await! cannot intercept the emission of the signal:

(thread-start! (instantiate::fthread (body (lambda () 
                                              (thread-await! 'foo)
                                              (broadcast! 'foo 1)))))
(thread-start! (instantiate::fthread (body (lambda () 
                                              (broadcast! 'foo 2)))))
Bigloo function: thread-get-values! signal

Terminates the instant for the thread (as thread-yield!) and returns, hence at the next instant, all the values associated with broadcast signal (see Section Signal) during the previous scheduler reaction (see Section Scheduler).

Example:

(thread-start! (instantiate::fthread
                  (body (lambda ()
                           (for-each print (thread-get-values! 'foo))))))
(thread-start! (instantiate::fthread
                  (body (lambda ()
                           (broadcast! 'foo 1)
                           (broadcast! 'foo 'foo)
                           (broadcast! 'foo "blabla")))))
   -| 1
      foo
      blabla

Example:

(let ((t1 (thread-start!
           (instantiate::fthread
              (body (lambda ()
                       (for-each print (thread-get-values! 'foo))))
              (name 't1))))
      (t2 (thread-start!
           (instantiate::fthread
              (body (lambda ()
                       (broadcast! 'foo (current-thread))
                       (thread-yield!)
                       ;; this second broadcast won't be intercepted 
                       ;; because it occurs during the next reaction
                       (broadcast! 'foo (current-thread))))
              (name 't2))))
      (t3 (thread-start!
           (instantiate::fthread
              (body (lambda ()
                       (broadcast! 'foo (current-thread))
                       (broadcast! 'foo (current-thread))))
              (name 't3)))))
   (scheduler-start!))
   -| #<thread:t2>
      #<thread:t3>
      #<thread:t3>
Bigloo function: thread-await-values! signal [timeout]

This blocks the current thread until signal has been broadcast. It then returns, at the next instant, all the values associated with all the broadcasts that took place during the instant. It can be defined as:

(define (thread-await-values! signal . tmt)
   (apply thread-await! signal tmt)
   (thread-get-values signal))
Bigloo function: thread-await*! signals [timeout]

Wait for one of a list of signals. The function thread-await*! can be compared to the Unix select function. The argument signals is a list of signal identifier. The function thread-await*! blocks the current thread until one of the signal in the list signals is broadcast or until the optional numerical argument timeout is elapsed. If the thread unblocks because the timeout is elapsed, thread-await*! returns #f. Otherwise it returns two values that have to be collected with multiple-value-bind (see Control features). The first one is the value of the broadcast signal. The second one is the broadcast signal.

Example:

(let ((res #f))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (let ((sig* (list 'foo 'bar)))
                   (multiple-value-bind (val1 sig1)
                      (thread-await*! sig*)
                      (multiple-value-bind (val2 sig2)
                         (thread-await*! sig*)
                         (thread-yield!)
                         (multiple-value-bind (val3 sig3)
                            (thread-await*! sig*)
                            (set! res (list sig1 sig2 sig3))))))))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 2)
                (broadcast! 'foo 1)))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 3)
                (broadcast! 'bar 2)))))
   (scheduler-start!)
   res)
  ⇒ '(foo foo bar)

A second example using timeouts:

(let ((res #f))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (let ((sig* (list 'foo 'bar)))
                   (multiple-value-bind (val1 sig1)
                      (thread-await*! sig* 1)
                      (thread-yield!)
                      (multiple-value-bind (val2 sig2)
                         (thread-await*! sig* 1)
                         (thread-yield!)
                         (multiple-value-bind (val3 sig3)
                            (thread-await*! sig* 2)
                            (set! res (list sig1 sig2 sig3))))))))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 2)
                (broadcast! 'foo 1)))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 3)
                (broadcast! 'bar 2)))))
   (scheduler-start!)
   res)
  ⇒ '(#f foo bar)
Bigloo function: thread-get-values*! signals

Terminates the instant for the thread (as thread-yield!) and returns, hence at the next instant, all the values associated with all broadcast signals (see Section Signal) during the previous scheduler reaction (see Section Scheduler). The function thread-get-values*! returns an alist made of the scanned signal and their values. That is the length of the returns list is the length of the list signals. If a signal of the list signals has not been broadcast, its associated entry the list returned by thread-get-values*! has an empty cdr.

Example:

(let ((s1 'foo)
      (s2 'bar)
      (s3 'gee)
      (res #f))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 2)
                (broadcast! 'foo (current-time))
                (broadcast! 'bar 0)))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-await*! (list s1 s2 s3))
                (set! res (thread-get-values*! (list s1 s2 s3)))))))
   (thread-start!
    (instantiate::fthread
       (body (lambda ()
                (thread-sleep! 2)
                (broadcast! 'bar (current-time))))))
   (scheduler-start!)
   res)
  ⇒ ((foo 3) (bar 3 0) (gee))

Used with asynchronous signal, the functions thread-await*! and thread-get-values*! can be used to read concurrently, in a non blocking way, several files.

Bigloo function: thread-await-values*! signals [timeout]

This blocks the current thread until at least one of signals has been broadcast. It then returns, at the next instant, all the values associated with all the broadcasts that took place during the instant. It can be defined as:

(define (thread-await-values*! signal . tmt)
   (apply thread-await*! signal tmt)
   (thread-get-values*! signal))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on March 31, 2014 using texi2html 5.0.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.