4 ms·
Technically there's no reason why write can't context switch directly to a process that's blocked on read (or, less commonly, vice versa). That only solves half
by a1369209993 7y ago
Technically there's no reason why write can't context switch directly to a process that's blocked on read (or, less commonly, vice versa). That only solves half the problem though; if you want pure pipe-like IO, you'd also need a single system call that combines write with select/poll/equivalent so the caller can immediately become blocked waiting for the return message.
- Animats 7y agoThat runs into a problem on a quick reply. Process A does the write on pipe AB, then gives up the CPU to B. A is still in ready to run state. B quickly generates a reply and writes it to pipe BA. But there's no read pending on pipe BA yet. So both processes are now in ready to run state, contending for the CPU, along with anything else that needed it. There's an alternative - unbuffered pipes. This is like a Go channel of length 0 - all writes block until the read empties the channel. This is better from a CPU dispatching perspective, in that a write to a channel implies an immediate transfer of control to the receiver. Of course, Go is doing this in one address space, not across a protection boundary. The QNX approach worked well for service-type requests. You could set up a service usable by multiple processes. Each request contained the info needed to send the reply back to the caller. The service didn't have to open a pipe to the requestor. This even understood process priority, so high priority requests were serviced first, an essential feature in a hard real time system.
- a1369209993 7y ago> That runs into a problem on a quick reply. Read the second sentence; process A does the write+select on AB and [BA,...], yields to B, is not ready to run; B generates a reply and writes it to BA, which has a read (technically select) already pending.
- Animats 7y agoThat's the advantage of a combined read and write. But if you're going to have that, it's more convenient to explicitly package it as a request/reply. Less trouble with things like having two messages in the pipe and such.
- a1369209993 7y agoYou might be waiting (via select) for multiple replies; you don't know whether B will (say) grab something out of disk cache and chuck it back to you, or if it'll fire off a seek command to the spinning rust and take a nap just as your network round-trip completes. Having two (or more) messages in (separate) pipes is the point of using select.