Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pipes vs asynchronous channels in Racket

Racket has both a notion of pipes and channels.

In the case of a pipe (created with make-pipe), any data written to the output port, can be read from the associated input port.

Channels are similar, but with one major difference: writing something to the input blocks until the output is simultaneously read. This is particularly useful for concurrency as it can be used for inter-thread communication and synchronization.

Racket also have a notion of asynchronous channels. These are similar to plain channels, but additionally have a buffer. If data is written to the buffer and it is not full, than the writing thread continues. The reading thread will block if the queue is empty, but otherwise it can read the latest data and continue on.

The question is, what is the difference between a pipe and an asynchronous channel? Clearly asynchronous channels were created with threads in mind, while pipes are independent of threading. But both APIs seem to serve a near identical purpose:

  1. Provide a (possibly infinite) buffer where some producer can put input.
  2. Provide an output for some consumer to get the data on the buffer.
  3. Allow the consumer to wait until data is available.
  4. Allow the producer to place input and continue execution.

The main difference between the two seems to be with the items placed in each. Pipes seem designed to mostly handle text (and bytes), and set their size accordingly. Where as channels handle items placed in the queue, rather than the size of those items themselves.

For example, a buffer size of '2' could hold a string with 2 bytes in it, while an asynchronous channel with a buffer size of '2' can hold 2 items, however large those items are.

This would lead one to think that maybe pipes are only used for text, where channels are more general. However, non-textual items can still be written to pipes, as shown with make-pipe-with-specials.

So, what is the different uses between asynchronous channels and pipes?

like image 725
Leif Andersen Avatar asked Jan 22 '26 03:01

Leif Andersen


1 Answers

Pipes are ports, and so carry bytes. Channels carry arbitrary values.

Certainly you can write some nontrivial value to a pipe and read it back on the other side. But fundamentally it's being converted into bytes, sent through the pipe, and turned back into a value on the other end. Channels skip that.

This means you can send values through channels that would not survive the trip through write and read and so can't be sent through a pipe. Unreadable values like structures that have a custom-write procedure and, well, ports!

This is my understanding. I haven't read the code. Just the documentation. I learned from the links you gave as well as the documentation for print-unreadable and The Printer.

like image 71
Lucas Paul Avatar answered Jan 23 '26 21:01

Lucas Paul