Re: [racket-users] Creating threads that prevent main thread from exiting

2020-11-16 Thread Matthew Flatt
Probably the right choice is to install a flush handler with the
current plumber:

 (define (thread/wait proc)
   (define t (thread proc))
   (plumber-add-flush! (current-plumber)
   (lambda (h) (thread-wait t)))
   t)

That adds a `thread-wait` in the same sense as flushing a stdout buffer
before exiting.


Another possibility is to extend the `executable-yield-handler`, which
the `racket` executable calls just before `exit`:

  (define (thread/wait proc)
(define t (thread proc))
(let ([old (executable-yield-handler)])
  (executable-yield-handler
   (lambda (v)
 (thread-wait t)
 (old v
t)

On difference between those strategies is that a new place won't call
the exectuable yield handler before the place exits, but a place does
tell its plumber to flush everything before exiting. That is, the
executable yield handler is meant to be specific to the whole process,
while plumbers are meant to be a nestable generalization. Another
difference is that the default exit handler triggered by `(exit)`
doesn't try to yield, but it does tell the plumber to flush.

At Mon, 16 Nov 2020 07:39:09 -0800 (PST), Greg Rosenblatt wrote:
> What is the best way to create threads that will prevent a program from 
> exiting until they have completed their work?   I'd like to be able to do 
> this implicitly, without cooperation from the main thread.
> 
> My first experiment uses `shift` to insert uses of `thread-wait` after the 
> rest of the program:
> 
> ```
> #lang racket
> (require racket/control)
> 
> (define (thread/wait proc)
>   (define t (thread proc))
>   (shift k (k t) (thread-wait t)))
> 
> (define t1 (thread/wait (lambda () (let loop () (displayln "t1") (sleep 2) 
> (loop)
> (define t2 (thread/wait (lambda () (let loop () (displayln "t2") (sleep 3) 
> (loop)
> 
> (displayln "end of main thread")
> ```
> 
> This doesn't work, seemingly due to an implicit `reset`/`prompt` around 
> each top-level definition/expression in a module.
> 
> Wrapping the entire module in a trivial `(let () _)` fixes the issue, but 
> this is not desirable:
> 
> ```
> #lang racket
> (require racket/control)
> 
> (let ()
>   (define (thread/wait proc)
> (define t (thread proc))
> (shift k (k t) (thread-wait t)))
> 
>   (define t1 (thread/wait (lambda () (let loop () (displayln "t1") (sleep 
> 2) (loop)
>   (define t2 (thread/wait (lambda () (let loop () (displayln "t2") (sleep 
> 3) (loop)
> 
>   (displayln "end of main thread"))
> ```
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/e67b750a-1d9d-42fa-9712-9c03da54
> 75a8n%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/20201116110601.240%40sirmail.smtps.cs.utah.edu.


[racket-users] Creating threads that prevent main thread from exiting

2020-11-16 Thread Greg Rosenblatt
What is the best way to create threads that will prevent a program from 
exiting until they have completed their work?   I'd like to be able to do 
this implicitly, without cooperation from the main thread.

My first experiment uses `shift` to insert uses of `thread-wait` after the 
rest of the program:

```
#lang racket
(require racket/control)

(define (thread/wait proc)
  (define t (thread proc))
  (shift k (k t) (thread-wait t)))

(define t1 (thread/wait (lambda () (let loop () (displayln "t1") (sleep 2) 
(loop)
(define t2 (thread/wait (lambda () (let loop () (displayln "t2") (sleep 3) 
(loop)

(displayln "end of main thread")
```

This doesn't work, seemingly due to an implicit `reset`/`prompt` around 
each top-level definition/expression in a module.

Wrapping the entire module in a trivial `(let () _)` fixes the issue, but 
this is not desirable:

```
#lang racket
(require racket/control)

(let ()
  (define (thread/wait proc)
(define t (thread proc))
(shift k (k t) (thread-wait t)))

  (define t1 (thread/wait (lambda () (let loop () (displayln "t1") (sleep 
2) (loop)
  (define t2 (thread/wait (lambda () (let loop () (displayln "t2") (sleep 
3) (loop)

  (displayln "end of main thread"))
```

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/e67b750a-1d9d-42fa-9712-9c03da5475a8n%40googlegroups.com.