举例:用迅雷下载电影
迅雷进程先在自己的栈区和内核开辟一块缓冲区。 通过系统调用让 DMA 控制器接管总线,自己阻塞让出 CPU 执行权限。 DMA 从网卡取数据,保存到内核缓冲区 内核缓冲区满后,DMA 通过中断通知 CPU 唤醒迅雷进程, 并把内核缓冲区的数据复制到用户栈的缓冲区 迅雷进程打开一个文件通过系统调用把用户栈缓冲区数据写入
重复从网卡取数据,缓冲区满了就保存到文件直到电影下载完
我理解的有错吗?
打开文件是重新在内核开辟一块缓冲区 然后把用户缓冲区的数据拷贝到这个内核缓冲区,再让 DMA 保存到磁盘 还是复用之前下载用的内核缓冲区?
能绕过用户缓冲区,直接使用内核缓冲区下载并保存吗?
还有保存到磁盘时,我查了下还有磁盘缓冲区这个东西,它是磁盘里的一块内存吗 那 DMA 传输的数据是谁和谁之间的?是内核缓冲区到磁盘缓冲区吗? 那磁盘缓冲区到磁盘的数据拷贝由谁控制? IO 控制器? DMA ,又或者驱动程序?
在内核开辟的内核缓冲区是专属迅雷这个进程吗? 其它进程能通过系统调用访问吗
1
sagaxu 2021-11-20 09:48:08 +08:00 via Android
1. 用户程序 buffer
2. IO 库 buffer 3. 操作系统 buffer 4. 文件系统 cache 5. 磁盘内置 buffer/cache 6. 磁盘持久化存储介质 |
2
choury 2021-11-20 10:29:34 +08:00 via Android
搜下 sendfile 和 splice 系统调用
|
3
Nitroethane 2021-11-20 16:41:12 +08:00
既然正在学操作系统,应该明白用户态进程是通过操作系统提供的系统调用与所需要的系统资源进行交互的。所以首先应该明确,迅雷下载一个文件的过程中与 i/o 相关的系统调用是什么。
“自己阻塞让出 CPU 执行权限”:当一个进程调用了阻塞的系统调用时,如果相应的资源没有准备好,那么这个进程就会被内核挂起,扔进等待队列里。当资源准备好后,内核会把进程扔进就绪队列,等待进程调度器调度进程继续运行。 “DMA 通过中断通知 CPU 唤醒迅雷进程”:硬件只能通过中断告诉内核数据准备好了。 我没了解过 Windows ,反正 Linux 上 I/O 相关的内核缓冲区对用户态进程是透明的。 |