The Master said, “Being upright, he did not obey orders; Its body is not straight, although the order does not follow.” The Analects of Confucius: Sub-Chapter
A hundred blog series. This is:
V70. Xx HongMeng kernel source code analysis (pipe file) | how to reduce the data flow cost
File system related sections are as follows:
- V62. Xx HongMeng kernel source code analysis concept (file) | why everything is the file
- V63. Xx HongMeng kernel source code analysis (file system) | said in books management file system
- V64. Xx HongMeng kernel source code analysis (inode) | who is the most important concept of file system
- V65. Xx HongMeng kernel source code analysis (mount directory) | why need to mount the file system
- V66. Xx HongMeng kernel source code analysis (the root file system) | on first
/
File system on - V67. Xx HongMeng kernel source code analysis (character device) | bytes read/write device for the unit
- V68. Xx HongMeng kernel source code analysis file system (VFS) | the foundation of the harmonious coexistence
- V69. Xx HongMeng kernel source code analysis (file handle) | why do you call a handle?
- V70. Xx HongMeng kernel source code analysis (pipe file) | how to reduce the data flow cost
What is a pipe
- Pipe | pipesThe earliest and clearest statement comes from
McIlroy
by1964
An internal document written in 1998. The document proposes to link programs together like garden hoses. The document is as follows:Summary--what's most important. To put my strongest concerns into a nutshell: 1. We should have some ways of coupling programs like garden hose--screw in another segment when it becomes when it becomes necessary to massage data in another way. This is the way of IO also. 2. Our loader should be able to do link-loading and controlled establishment. 3. Our library filing scheme should allow for rather general indexing, responsibility, generations, data path switching. 4. It should be possible to get private system components (all routines are system components) for buggering around with. M. D. McIlroy October 11, 1964 Copy the code
Unix
The architect of theKen Thompson
It took only an hour to implement the system call to the pipe in the operating system. He said it was a piece of cake because the I/O redirection mechanism was the foundation of the pipeline, but the effect was impressive. The essence of a pipeline isI/O
Redirection is the constant editing, constant flow of data, only such data is valuable.- As mentioned in the Document Concept section,
Unix
The “everything is a file” argument stems from the commonality of inputs and outputs, which can and should be abstracted into unified file management and flow. Take the development of cities for example, the more frequent the population flow and capital flow, the more developed the city must be. Please carefully appreciate this truth. The planning of the city should make the cost of flow lower and the time shorter, rather than checking the ID card and household registration book everywhere. For kernel designers, too, a system that makes the cost of data flow extremely simple and convenient must be a good architecture,Unix
One of the big reasons it’s been so successful for so many years is that it only uses one|
Symbols implement the problem of fluidity between files. It is a great innovation, and deserves a special chapter on it.
Pipe symbol|
Pipe symbol is a vertical bar | between two commands, simple and elegant, for example, the ls is used to display a directory file, wc for statistical rows. Ls | wc represents a certain number of files in the directory Take a look at a complex:
$ < colors.txt sort | uniq -c | sort -r | head -3 > favcolors.txt
Copy the code
colors.txt
For the original file content, output tosort
To deal withsort
对colors.txt
The contents are sequentially edited and output touniq
To deal withuniq
To de-edit the content and output tosort -r
To deal withsort -r
Edit content in reverse order and output tohead -3
To deal withhead -3
Take the first three edits of the content and output tofavcolors.txt
Save the file.- The last
cat favcolors.txt
View the results$ cat favcolors.txt 4 red 3 blue 2 green Copy the code
Classic Pipe Case
The following is a classic example of a Linux official pipeline. Check the pipe
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child reads from pipe */
close(pipefd[1]); /* Close unused write end */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Parent writes argv[1] to pipe */
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
}
Copy the code
Interpretation of the
pipe(pipefd)
For the system call, two file handles are applied and piped to the two files. The system call in hongmeng pipeline isSysPipe
To implement it, look down.main
processfork()
A subprocess, specificfork
Process, please go to [v45. Xx (Fork) | one call, two return] turn. The child will copy the parent’s file resources. So the child processcpid
Also has thepipefd
Two handles, meaning you can manipulate thempipefd
Corresponding fileif (cpid == 0)
Represents the return of the child process,close(pipefd[1])
Shut down thepipefd[1]
File handle. Because the program is designed for child processes to read files, it does not require operationspipefd[1]
while (read(pipefd[0], &buf, 1)
The child process continuously reads the filepipefd[0]
The content of the.- It’s supposed to keep reading
pipefd[0]
The data shows that there is a process going onpipefd[0]
But the idea of the pipe is topipefd[1]
To write data, data can run topipefd[0]
In the.
(cpid > 0)
That’s in the code} else {
Represents the parent processmain
The return.close(pipefd[0])
Shut down thepipefd[0]
File handle. Because the program is designed to write files to the parent process, it does not need to operatepipefd[0]
write(pipefd[1], argv[1], strlen(argv[1]))
The parent process topipefd[1]
Data will appear in thepipefd[0]
For the child process to read.
HongMeng implementation
The implementation of the pipe’s function-level call relationship is as follows:
SysPipe // system call AllocProcessFd // allocate two process descriptors pipe // true implementation of the underlying pipe pipe_ALLOCATE pipe "/dev/pipe%d" // generate create pipe file path, used to create two system file handles Pipecommon_allocdev // Allocate space shared by the piperegister_driver // Register the pipedevice driver open // Open two system file handles fs_getFilep // Obtain the entity object 'file' for two system file handles AssociateSystemFd // Binding of process and system file handlesCopy the code
Pipe is the most important one, it is the implementation of the pipe idea of the implementation of the implementation of the code, a little bit of code, but understand this function to understand the pipe completely, before reading the file system is recommended to read the length of the code and interpretation of the foundation is easy to understand.
int pipe(int fd[2]) { struct pipe_dev_s *dev = NULL; char devname[16]; int pipeno; int errcode; int ret; struct file *filep = NULL; size_t bufsize = 1024; /* Get exclusive access to the pipe allocation data */ ret = sem_wait(&g_pipesem); if (ret < 0) { errcode = -ret; goto errout; } /* Allocate a minor number for the pipe device */ pipeno = pipe_allocate(); if (pipeno < 0) { (void)sem_post(&g_pipesem); errcode = -pipeno; goto errout; } /* Create a pathname to the pipe device */ snprintf_s(devname, sizeof(devname), sizeof(devname) - 1, "/dev/pipe%d", pipeno); /* No.. Allocate and initialize a new device structure instance */ dev = pipecommon_allocdev(bufsize, devname); if (! dev) { (void)sem_post(&g_pipesem); errcode = ENOMEM; goto errout_with_pipe; } dev->d_pipeno = pipeno; /* Check if the pipe device has already been created */ if ((g_pipecreated & (1 << pipeno)) == 0) { /* Register the pipe device */ ret = register_driver(devname, &pipe_fops, 0660, (void *)dev); if (ret ! = 0) { (void)sem_post(&g_pipesem); errcode = -ret; goto errout_with_dev; } /* Remember that we created this device */ g_pipecreated |= (1 << pipeno); } else { UpdateDev(dev); } (void)sem_post(&g_pipesem); /* Get a write file descriptor */ fd[1] = open(devname, O_WRONLY); if (fd[1] < 0) { errcode = -fd[1]; goto errout_with_driver; } /* Get a read file descriptor */ fd[0] = open(devname, O_RDONLY); if (fd[0] < 0) { errcode = -fd[0]; goto errout_with_wrfd; } ret = fs_getfilep(fd[0], &filep); filep->ops = &pipe_fops; ret = fs_getfilep(fd[1], &filep); filep->ops = &pipe_fops; return OK; errout_with_wrfd: close(fd[1]); errout_with_driver: unregister_driver(devname); errout_with_dev: if (dev) { pipecommon_freedev(dev); } errout_with_pipe: pipe_free(pipeno); errout: set_errno(errcode); return VFS_ERROR; }Copy the code
Interpretation of the
- The amount of pipe in Hongmeng is also limited and managed by bitmaps, with a maximum of 32 supported, using a 32-bit variable
g_pipeset
Enough, bitmap how to manage please see bitmap management. To use it, you have to applypipe_allocate
Be responsible for.#define MAX_PIPES 32 static sem_t g_piPESem = {NULL}; static uint32_t g_pipeset = 0; // Static uint32_t g_pipecreated = 0; static inline int pipe_allocate(void) { int pipeno; int ret = -ENFILE; for (pipeno = 0; pipeno < MAX_PIPES; pipeno++) { if ((g_pipeset & (1 << pipeno)) == 0) { g_pipeset |= (1 << pipeno); ret = pipeno; break; } } return ret; }Copy the code
- What looks like two files on the outside of the pipe is actually reading and writing to a block of memory. Operation memory will need to apply for memory blocks, hongmeng default use
1024 | 1K
Memory, you need file paths to manipulate files/dev/pipe%d
.size_t bufsize = 1024; snprintf_s(devname, sizeof(devname), sizeof(devname) - 1, "/dev/pipe%d", pipeno); dev = pipecommon_allocdev(bufsize, devname); Copy the code
- This is followed by providing action files
/dev/pipe%d
theVFS
That is, register file system driver, upper read and write operations, to the bottom of the real read and write is bypipecommon_read
andpipecommon_write
Fall to the ground.ret = register_driver(devname, &pipe_fops, 0660, (void *)dev); static const struct file_operations_vfs pipe_fops = { .open = pipecommon_open, /* open */ .close = pipe_close, /* close */ .read = pipecommon_read, /* read */ .write = pipecommon_write, /* write */ .seek = NULL, /* seek */ .ioctl = NULL, /* ioctl */ .mmap = pipe_map, /* mmap */ .poll = pipecommon_poll, /* poll */ #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS .unlink = pipe_unlink, /* unlink */ #endif }; Copy the code
pipecommon_read
There’s a lot of code, I won’t show it here, but there’s a lot of semaphore in the code, just to make sure that this shared memory works. - To operate on both file handles, you have to open both files, but one to read and one to write,
pipe
The default is tofd[1]
As written,fd[0]
In order to read, we can scroll back here to look at the reading process of the classic pipe case.fd[1] = open(devname, O_WRONLY); fd[0] = open(devname, O_RDONLY); Copy the code
- The final binding
file
The file interface operation, as detailed in the file handle section, that the application operates onFd | file handle
, to the kernel is required to passfd
findfile
, and then findfile->ops
To actually manipulate the file.ret = fs_getfilep(fd[0], &filep); filep->ops = &pipe_fops; ret = fs_getfilep(fd[1], &filep); filep->ops = &pipe_fops; Copy the code
Intensive reading of the kernel source code
Four code stores synchronous annotation kernel source code, >> view the Gitee repository
Analysis of 100 blogs. Dig deep into the core
Add comments to hongmeng kernel source code process, sort out the following article. Content based on the source code, often in life scene analogy as much as possible into the kernel knowledge of a scene, with a pictorial sense, easy to understand memory. It’s important to speak in a way that others can understand! The 100 blogs are by no means a bunch of ridiculously difficult concepts being put forward by Baidu. That’s not interesting. More hope to make the kernel become lifelike, feel more intimate. It’s hard, it’s hard, but there’s no turning back. 😛 and code bugs need to be constantly debug, there will be many mistakes and omissions in the article and annotation content, please forgive, but will be repeatedly amended, continuous update. Xx represents the number of modifications, refined, concise and comprehensive, and strive to create high-quality content.
Compile build | The fundamental tools | Loading operation | Process management |
---|---|---|---|
Compile environment The build process Environment script Build tools Designed.the gn application Ninja ninja |
Two-way linked list Bitmap management In the stack way The timer Atomic operation Time management |
The ELF format The ELF parsing Static link relocation Process image |
Process management Process concept Fork Special process Process recycling Signal production Signal consumption Shell editor Shell parsing |
Process of communication | Memory management | Ins and outs | Task management |
spinlocks The mutex Process of communication A semaphore Incident control The message queue |
Memory allocation Memory management Memory assembly The memory mapping Rules of memory Physical memory |
Total directory Scheduling the story Main memory slave The source code comments Source structure Static site |
The clock task Task scheduling Task management The scheduling queue Scheduling mechanism Thread concept Concurrent parallel The system calls Task switching |
The file system | Hardware architecture | ||
File concept The file system The index node Mount the directory Root file system Character device VFS File handle Pipeline file |
Compilation basis Assembly and the cords Working mode register Anomaly over Assembly summary Interrupt switch Interrupt concept Interrupt management |
HongMeng station | into a little bit every day, the original is not easy, welcome to reprint, please indicate the source.