FIFO (named pipe)
Niko rushes into the office. “Nini! Help! Our client’s server has a process that is stuck! It just hangs and never finishes!”
Nini looked up from her screen 黑人問號 and asked. “A stuck process? Or is it waiting for something?”
“Let me teach you some basics about pipe. This will be a piece of fish.” “First, let’s create a simple named pipe,” Nini said. Now it’s your turn. Open a terminal and follow along with Niko’s debugging session. Your Task: Create a pipe and try to write the current time into it. After running the second command, you will see that your terminal is “stuck”. It doesn’t return to the command prompt. This is what Niko saw on the client’s server. This is blocking. The Your Task: Press Nini continued: “Now let’s see what happens with multiple writers.” Your Task: Create two new pipes, Your Task: Now, run the following commands. The “Good,” said Nini. “Now, let’s dig deeper and investigate one of the background processes.” Your Task: In a new terminal window (since your other one is blocked), investigate one of the PIDs you noted down. Replace Look at the output. What system call is your process stuck in? It is waiting for something to happen. Do you see the file descriptor for the pipe you opened? Is the process name what you expect? “The writers are all patiently waiting,” Nini explained. “They will remain blocked until a reader opens the other end of the pipe. Let’s unblock them.” Your Task: In the terminal where you ran the As soon as you run Question: Look at the output. Are the timestamps from “The Your Task: First, clean up the old pipes and create new ones. Next, create a shell alias. This is a shortcut for a longer command. Your Task: Now, run the writers again, just like before. And then, read the results. Question: Compare the microsecond precision of the timestamps in your output. Are they identical or different? How do they compare to the Question: Why might Python show different microsecond values while the “Okay, final test,” Nini said. “You have seen what happens when the writer starts before the reader. What do you predict will happen if you start the reader before any writers?” Your Task: Let’s run the experiment. First, start over again: Now, run the reader ( Observe what happened in your terminal.Basic Pipe Behavior
mkfifo F
date +%s > F
date
command is waiting because no process is reading from the other end of the pipe.Ctrl+C
to interrupt the command and get your prompt back. Then, verify that you created a pipe using ls -l
. The file F
should have a type p.Investigating Multiple Blocked Processes
A
and B
.mkfifo A
mkfifo B
&
symbol will run the first two commands in the background. Your terminal will block on the third command. Take note of the Process IDs (PIDs) that are printed for the background jobs.date +%s > A &
date +%s > B &
date +%s > C
[PID]
with the actual process ID.ps aux | grep [PID]
strace
to see what the process is asking the kernel to do.strace -p [PID]
/proc
: The /proc
filesystem gives you a direct look into the kernel’s data about processes.cat /proc/[PID]/cmdline # show the process's command
ls /proc/[PID]/fdinfo/ # list open file descriptors
cat /proc/[PID]/fdinfo/* # see details about the file descriptors
Reading from the Pipes
strace
and ps
commands, run cat
. This command will read from the pipes.cat -n A B
cat C
cat
, you will see the timestamps appear. cat
reads the data, which unblocks the waiting date
processes, allowing them to finish. Your original terminal will also become unblocked.A
and C
the same?A Test of Precision with Python
date
command only has a precision of one second,” Nini explained. “Let’s try an experiment with more precise timing. We will use a simple Python command to get microseconds.”rm A B
mkfifo A B
alias P='python3 -c "from datetime import datetime; print(datetime.now().strftime(\"%H:%M:%S.%f\"))"'
P > B &
P > A &
P > C
cat -n A B C
date
command results from earlier?date
command showed identical timestamps?Order Dependency
rm A B
mkfifo A B
cat
) in the background first, then run the writers.cat -n A B &
date +%s > A &
date +%s > B &
date
) block, or did they execute immediately?
Questions
Nini smiled. “You’ve done well. You have seen how processes communicate with pipes. Now, to make sure you understood, answer these questions.”
When you ran
date +%s > A &
, what was the process name shown byps
? Was itdate
? Why or why not? (Hint: Think about what the shell does before it runs thedate
command).Why did your Python experiment show different microsecond timestamps while the
date
commands showed identical timestamps? (Hint: Think about how many processes are created and when the timestamps are generated).Here is a simplified C code snippet that shows what the shell does to run a command like
date > A
. Explain what thedup2
system call does. At which point —(1)
,(2)
,(3)
, or(4)
— does the writer process block if no reader is present?
int main() {
;
pid_t pid
= fork();
pid if (pid == 0) { // This is the child process
/* (1) */
int fd = open("A", O_WRONLY);
/* (2) */
(fd, STDOUT_FILENO); // STDOUT_FILENO is file descriptor 1
dup2(fd);
close
/* (3) */
("date", "date", NULL); // Replace this process with 'date'
execlp}
/* (4) */ // This is the parent process
}