[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Concurrently write (out) and read (in) from ports
From: |
Zelphir Kaltstahl |
Subject: |
Concurrently write (out) and read (in) from ports |
Date: |
Tue, 11 Apr 2023 21:13:19 +0000 |
Hi Guile users!
I am currently trying to concurrently write to an output port and read from the
corresponding input port, but something I am doing wrong and it does not work as
I expected it to.
Here is what I have tried so far:
~~~~
(import
;; ports
(ice-9 popen)
(ice-9 textual-ports)
(ice-9 binary-ports)
(ice-9 exceptions)
(ice-9 match)
(ice-9 threads)
(ice-9 futures)
;; let-values form
(srfi srfi-11))
;; Define a pair of corresponding in and out ports.
(define-values (in out)
(match-let ([(in . out) (pipe)])
;; make out line buffered
;; (setvbuf out 'line)
(values in out)))
;; Just a helper function.
(define seconds
(λ (s)
(* s (expt 10 6))))
(define line-reader
(λ ()
"Read from an IN-PORT and write to OUT-PORT."
(let ([in-port (current-input-port)]
[out-port (current-output-port)])
(let loop ([line (get-line in-port)])
(simple-format #t "reader: reading from in-port\n")
(unless (eof-object? line)
(put-string out-port line)
(loop (get-line in-port)))))))
;; Start writing endlessly.
(define writer-future
(future
(with-output-to-port out
(λ () (endless-writer)))))
(with-output-to-port (current-output-port)
(λ ()
(with-input-from-port in
(line-reader))))
~~~~
However, this does not work:
~~~~
guile -L . example.scm
~~~~
Does not display anything.
I also tried with explicitly passed ports:
~~~~
(import
;; ports
(ice-9 popen)
(ice-9 textual-ports)
(ice-9 binary-ports)
(ice-9 exceptions)
;; receive form
;; (ice-9 receive)
;; pattern matching
(ice-9 match)
;; concurrency
(ice-9 threads)
(ice-9 futures)
;; let-values form
(srfi srfi-11))
(define-values (in out)
(match-let ([(in . out) (pipe)])
;; make out line buffered
;; (setvbuf out 'none)
(values in out)))
(define seconds
(λ (s)
(* s (expt 10 6))))
(define endless-writer
(λ (out)
(let loop ()
(simple-format #t "writer: writing message to output port\n")
(put-string out "Hello!\n")
;; forcing the output should be unnecessary
;; (force-output out)
(usleep (seconds 1))
(loop))
'never))
(define line-reader
(lambda* (in-port out-port)
"Read from an IN-PORT and write to OUT-PORT."
(let loop ([line (get-line in-port)])
(simple-format #t "reader: reading from in-port\n")
(unless (eof-object? line)
(put-string out-port line)
(loop (get-line in-port))))))
;; Start writing endlessly.
(define writer-future (future (endless-writer out)))
;; Read from in-port, which should be the corresponding one to the
;; out-port, to which the endless-writer writes its output. Output to
;; the current output port, so that the output is visible. Read some
;; number of bytes at once. Limits the amount of memory needed for the
;; string.
(reader in (current-output-port) #:bytes-count 16)
;; That does not output anything.
(line-reader in (current-output-port))
;; That does not output anything.
~~~~
But:
~~~~
(call-with-input-string "Test!\n"
(lambda (in)
(line-reader in (current-output-port))))
~~~~
Does output things.
So I am thinking my endless writer must be wrong. But I cannot figure out what
is wrong. Or maybe I am misunderstanding how the in and out port of (pipe)
correspond.
How can I make this work?
Also side question: Is this usage of futures "OK", or should I be using threads?
Thought futures are more lightweight than threads in this case.
Regards,
Zelphir
--
repositories:https://notabug.org/ZelphirKaltstahl
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Concurrently write (out) and read (in) from ports,
Zelphir Kaltstahl <=