Linux/Unix中两个程序能否同时访问stdin及C/C++实现方法
Great question! Let's break this down clearly—yes, two programs (or processes) can access the same stdin in Linux/Unix, but the behavior depends entirely on what stdin is connected to. Here's the full breakdown plus C/C++ implementations:
Short answer: Yes, but with critical caveats based on the type of input source:
- If
stdinpoints to a regular disk file, multiple processes can read from it independently. Each process maintains its own file offset, so you can control which parts of the file each process reads. - If
stdinis a stream-oriented device (like a terminal, pipe, or socket), multiple processes can read from it, but they'll compete for input. Once a byte is read by one process, it's gone—there's no way to "share" the same data between them.
Scenario 1: Sharing a Regular File as stdin
When stdin is redirected to a file (e.g., running ./myprogram < input.txt), you can create a child process that inherits the stdin file descriptor. Each process can seek to different offsets and read without interfering.
C Implementation Using fork()
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> int main() { pid_t child_pid = fork(); if (child_pid == -1) { perror("Failed to create child process"); return 1; } if (child_pid == 0) { // Child process: read the first 15 bytes of the file char buffer[16]; fseek(stdin, 0, SEEK_SET); size_t bytes_read = fread(buffer, 1, 15, stdin); buffer[bytes_read] = '\0'; printf("Child process read: '%s'\n", buffer); return 0; } else { // Parent process: wait for child, then read the next 15 bytes wait(NULL); // Optional: skip this if you want parallel reads char buffer[16]; fseek(stdin, 15, SEEK_SET); size_t bytes_read = fread(buffer, 1, 15, stdin); buffer[bytes_read] = '\0'; printf("Parent process read: '%s'\n", buffer); return 0; } }
Notes:
- After
fork(), the child inherits a copy of the parent's file descriptors, includingstdin. Each process has its own file offset, sofseekonly affects the current process's position. - If you don't use
fseek, the parent and child will continue reading from the offset where the other left off (since the initial offset is copied at fork time).
Scenario 2: Sharing a Stream Device (Terminal/Pipe) as stdin
For terminals, pipes, or sockets, input is a continuous stream. Multiple processes can read from stdin, but they'll race to consume data. Here's an example where parent and child both read from terminal input:
C Implementation
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> int main() { pid_t child_pid = fork(); if (child_pid == -1) { perror("Failed to create child process"); return 1; } if (child_pid == 0) { // Child process: read lines until "quit" char buffer[256]; printf("Child: Type input (or 'quit' to exit)\n"); while (fgets(buffer, sizeof(buffer), stdin) != NULL) { if (strcmp(buffer, "quit\n") == 0) { printf("Child: Exiting now\n"); break; } printf("Child received: %s", buffer); } return 0; } else { // Parent process: read lines until "quit" char buffer[256]; printf("Parent: Type input (or 'quit' to exit)\n"); while (fgets(buffer, sizeof(buffer), stdin) != NULL) { if (strcmp(buffer, "quit\n") == 0) { printf("Parent: Exiting now\n"); break; } printf("Parent received: %s", buffer); } wait(NULL); return 0; } }
What to Expect:
- When you type input, the kernel will send chunks of data to whichever process is waiting for input first. For terminal input (which is line-buffered), you'll usually get full lines delivered to one process or the other—but there's no guarantee.
- Once a process reads a piece of input, it's consumed forever; the other process can't access it.
Key Takeaways
- Regular files: Safe to share
stdinacross processes, with control over which parts each process reads via file offsets. - Stream devices: Multiple processes can read from
stdin, but they compete for input data—no sharing of the same bytes. - In C/C++,
fork()is the simplest way to create a child process that inherits the parent'sstdin. If you need to launch a separate unrelated program, you can redirect itsstdinto the same source (e.g., using pipes or terminal redirection).
内容的提问来源于stack exchange,提问作者pro neon

