C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

这篇具有很好参考价值的文章主要介绍了C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。
如果觉得本文能帮到您,麻烦点个赞👍呗!

近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️
Qt5.9专栏定期更新Qt的一些项目Demo
项目与比赛专栏定期更新比赛的一些心得面试项目常被问到的知识点。

Linux Web Server项目虽然是现在C++求职者的人手一个的项目,但是想要吃透这个项目,还是需要一定的基础的,以项目为导向,进行基础的学习。

涵盖了计算机网络(网络编程)常见的知识点和常见的操作系统知识

博主参加过大大小小的互联网厂和银行的秋招和春招的笔试与面试,整理了下面的2万7千字的长文(😄都是干货,写作不易啊),喜欢,觉得有帮助的,欢迎订阅专栏,后续有很多优质的文章进行更新,有任何疑问,欢迎留言!
C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

1、线程间的通信方式

同个进程下的线程之间都是共享进程的资源,只要是共享变量都可以做到线程间通信,比如全局变量,所以对于线程间关注的不是通信方式,而是关注多线程竞争共享资源的问题,信号量也同样可以在线程间实现互斥与同步:

  • 互斥的方式,可保证任意时刻只有一个线程访问共享资源;
  • 同步的方式,可保证线程 A 应在线程 B 之前执行;

2、简述Linux零拷贝的原理?

  1. 什么是零拷贝

    所谓「零拷贝」描述的是计算机操作系统当中,CPU不执行将数据从一个内存区域,拷贝到另外一个内存区域的任务。通过网络传输文件时,这样通常可以节省 CPU 周期和内存带宽。

  2. 零拷贝的好处

    (1)节省了 CPU 周期,空出的 CPU 可以完成更多其他的任务

    (2)减少了内存区域之间数据拷贝,节省内存带宽

    (3)减少用户态和内核态之间数据拷贝,提升数据传输效率

    (4)应用零拷贝技术,减少用户态和内核态之间的上下文切换

3、为什么要有DMA技术

如果没有直接内存访问DMA 则CPU 一直参与搬运

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

  • DMA 收到磁盘的信号,将磁盘控制器缓冲区中的数据拷贝到内核缓冲区中,此时不占用 CPU,CPU 可以执行其他任务

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

4、传统的文件拷贝的不足

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

要想提高文件传输的性能,就需要减少「用户态与内核态的上下文切换」和「内存拷贝」的次数

5、如何减少[数据拷贝]的次数?

从上图中国可以看到,内核区的缓存是没有必要的,通过避免这一缓存可以减少数据拷贝的次数。

在操作系统中,减少数据拷贝的次数是提高性能和效率的重要手段之一。以下是一些常见的减少数据拷贝次数的方法:

  1. 零拷贝(Zero-copy):零拷贝技术是一种可以在不拷贝数据的情况下进行数据传输的技术。在使用零拷贝技术时,内核将应用程序的缓冲区映射到系统内核空间的缓冲区中,然后直接将数据传输到目标设备或缓冲区中,从而避免了多次数据拷贝的操作。
  2. 内核缓冲区复制:在某些情况下,如果应用程序需要在进程间传输数据,可以使用内核缓冲区复制技术,这种技术将数据从一个进程的用户空间缓冲区复制到内核空间的缓冲区,然后再将数据从内核空间的缓冲区复制到另一个进程的用户空间缓冲区,避免了不必要的用户空间和内核空间的切换。
  3. 分页技术:分页技术可以将数据拆分成多个小块,每个小块都有自己的页表。这样在进行数据传输时,只需要传输需要的页,而不需要拷贝整个数据,从而避免了不必要的数据拷贝。
  4. 预先分配空间:预先分配空间可以避免在传输数据时动态分配内存的开销。如果应用程序需要传输大量数据,可以在传输之前预先分配足够的空间,这样在传输时就不需要动态分配内存,从而减少数据拷贝的次数。
  5. 操作系统缓存:一些操作系统提供了数据缓存功能,可以缓存数据以避免重复的拷贝。在数据传输时,如果数据已经被缓存,可以直接使用缓存中的数据,避免了不必要的数据拷贝。

这些技术都可以在不同的场景中使用,以提高操作系统的性能和效率。

6、如何实现零拷贝

零拷贝技术实现的方式:

  • mmap + write
  • sendfile

mmap + write

mmap() 替换 read() 系统调用函数

buf = mmap(file, len);
write(sockfd, buf, len);

系统调用函数会直接把内核缓冲区里的数据「映射」到用户空间.

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

零拷贝(*Zero-copy*)技术,因为我们没有在内存层面去拷贝数据,也就是说全程没有通过 CPU 来搬运数据,所有的数据都是通过 DMA 来进行传输的。

在 Linux 中,可以通过使用零拷贝技术来减少数据拷贝的次数,从而提高数据传输的效率。零拷贝技术是指在数据传输的过程中,尽可能地减少 CPU 和内存的拷贝操作,从而降低数据传输的延迟和 CPU 占用率。

下面给出两个示例代码,分别演示了如何在 Linux 中使用零拷贝技术进行文件传输和网络传输。

  1. 文件传输

使用 mmap 系统调用将文件映射到内存中,然后使用 sendfile 系统调用将文件从内存中传输到网络中,从而避免了数据在用户空间和内核空间之间的拷贝。

#include <sys/sendfile.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

int main()
{
    int in_fd = open("file.txt", O_RDONLY);
    struct stat stat_buf;
    fstat(in_fd, &stat_buf);
    off_t offset = 0;
    sendfile(STDOUT_FILENO, in_fd, &offset, stat_buf.st_size);
    close(in_fd);
    return 0;
}

  1. 网络传输

    使用 splice 系统调用将数据从一个文件描述符传输到另一个文件描述符,从而避免了数据在用户空间和内核空间之间的拷贝。

#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr = {0};
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(8080);
    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    listen(sockfd, 10);
    int connfd = accept(sockfd, NULL, NULL);
    int filefd = open("file.txt", O_RDONLY);
    int flags = SPLICE_F_MOVE | SPLICE_F_NONBLOCK;
    splice(filefd, NULL, connfd, NULL, 4096, flags);
    close(filefd);
    close(connfd);
    close(sockfd);
    return 0;
}

需要注意的是,零拷贝技术的使用需要考虑诸多因素,如硬件支持、内核版本等,同时也需要谨慎使用,避免出现数据丢失或破坏等问题。

7、大文件传输用什么方式实现?

那针对大文件的传输,我们应该使用什么方式呢?

我们先来看看最初的例子,当调用 read 方法读取文件时,进程实际上会阻塞在 read 方法调用,因为要等待磁盘数据的返回,如下图:

C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)

具体过程:

  • 当调用 read 方法时,会阻塞着,此时内核会向磁盘发起 I/O 请求,磁盘收到请求后,便会寻址,当磁盘数据准备好后,就会向内核发起 I/O 中断,告知内核磁盘数据已经准备好;
  • 内核收到 I/O 中断后,就将数据从磁盘控制器缓冲区拷贝到 PageCache 里;
  • 最后,内核再把 PageCache 中的数据拷贝到用户缓冲区,于是 read 调用就正常返回了。

对于阻塞的问题,可以用异步 I/O 来解决

它把读操作分为两部分:

  • 前半部分,内核向磁盘发起读请求,但是可以不等待数据就位就可以返回,于是进程此时可以处理其他任务;
  • 后半部分,当内核将磁盘中的数据拷贝到进程缓冲区后,进程将接收到内核的通知,再去处理数据;

而且,我们可以发现,异步 I/O 并没有涉及到 PageCache,所以使用异步 I/O 就意味着要绕开 PageCache。

绕开 PageCache 的 I/O 叫直接 I/O,使用 PageCache 的 I/O 则叫缓存 I/O。通常,对于磁盘,异步 I/O 只支持直接 I/O。

前面也提到,大文件的传输不应该使用 PageCache,因为可能由于 PageCache 被大文件占据,而导致「热点」小文件无法利用到 PageCache。

于是,在高并发的场景下,针对大文件的传输的方式,应该使用「异步 I/O + 直接 I/O」来替代零拷贝技术

直接 I/O 应用场景常见的两种:

  • 应用程序已经实现了磁盘数据的缓存,那么可以不需要 PageCache 再次缓存,减少额外的性能损耗。在 MySQL 数据库中,可以通过参数设置开启直接 I/O,默认是不开启;
  • 传输大文件的时候,由于大文件难以命中 PageCache 缓存,而且会占满 PageCache 导致「热点」文件无法充分利用缓存,从而增大了性能开销,因此,这时应该使用直接 I/O。

另外,由于直接 I/O 绕过了 PageCache,就无法享受内核的这两点的优化:

  • 内核的 I/O 调度算法会缓存尽可能多的 I/O 请求在 PageCache 中,最后「合并」成一个更大的 I/O 请求再发给磁盘,这样做是为了减少磁盘的寻址操作;
  • 内核也会「预读」后续的 I/O 请求放在 PageCache 中,一样是为了减少对磁盘的操作;

于是,传输大文件的时候,使用「异步 I/O + 直接 I/O」了,就可以无阻塞地读取文件了。

所以,传输文件的时候,我们要根据文件的大小来使用不同的方式:

  • 传输大文件的时候,使用「异步 I/O + 直接 I/O」;

  • 传输小文件的时候,则使用「零拷贝技术」;

参考资料

图片部分来源于小林Coding图解操作系统(非常推荐!!!)小林coding

最后,最后
如果觉得有用,麻烦三连👍⭐️❤️支持一下呀,希望这篇文章可以帮到你,你的点赞是我持续更新的动力文章来源地址https://www.toymoban.com/news/detail-425729.html

到了这里,关于C++ Linux Web Server 面试基础篇-操作系统(四、线程通信)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WEB安全基础入门—操作系统命令注入(shell 注入)

    欢迎关注订阅专栏! WEB安全系列包括如下三个专栏: 《WEB安全基础-服务器端漏洞》 《WEB安全基础-客户端漏洞》 《WEB安全高级-综合利用》 知识点全面细致,逻辑清晰、结合实战,并配有大量练习靶场,让你读一篇、练一篇,掌握一篇,在学习路上事半功倍,少走弯路! 欢

    2024年02月01日
    浏览(40)
  • Linux操作系统基础

    目录 计算机存储结构 冯.诺依曼结构 操作系统  在前几期我们学写了linux中常见的一些指令,本期我们将正式进行linux操作系统的学习。 要学习linux操作系统,我们就得先进行计算机存储结构的学习,要进行计算机存储结构的学习,我们就得先学习冯.诺依曼结构。 讲述冯诺依

    2024年01月16日
    浏览(35)
  • 【Linux面试题及答案:了解Linux操作系统、常见发行版及基本命令】

    一、什么是Linux操作系统? 答:Linux是一种开源的操作系统,它基于UNIX操作系统开发而来。Linux具有稳定性、可靠性和安全性的特点,并且可以运行在各种硬件平台上。 二、Linux有哪些常见的发行版? 答:Linux有许多不同的发行版,常见的有Ubuntu、Debian、CentOS、Fedora、Red Hat等

    2024年02月08日
    浏览(37)
  • 【Linux操作系统】【综合实验一 Linux操作基础】【浅试Linux命令】

    Linux均以文件形式存在 本文出现的命令浅尝辄止,具体使用参考文档即可 解决一个任务的方法很多,本文仅浅试了一些简单的命令 要求掌握Linux基础操作,熟悉Linux行界面,并 明白操作的原理以及目的(难) ;熟悉Linux系统环境。 通过这个第一阶段实验,要求掌握以下操作

    2023年04月08日
    浏览(90)
  • Linux云计算之Linux基础1——操作系统理论基础

    目录 1、UNIX 的诞生和广泛使用 2、CPU 架构类型 3、CPU 指令 4、计算机程序设计和执行过程 5、操作统OS 6、编程层次 7、程序的内部运行接口 8、UI程序接口(人机交互接口) 9、程序的运行模式: 10、POSIX:可移植操作系统规范 11、计算机开源领域 12、Linux 发行版:(商业和社区) 这里

    2024年04月08日
    浏览(57)
  • Linux操作系统学习,Linux基础命令大全

    友情提醒 先看文章目录,大致了解文章知识点结构,点击文章目录可直接跳转到文章指定位置。 ①Linux是基于Unix的开源的免免费的一款操作系统,由于系统的稳定性和安全性被成为程序代码运行的最佳操作系统环境。 ②Linux发行版的不同,可以分为 1)乌班图:Ubuntu 2)红帽

    2024年02月14日
    浏览(50)
  • Linux操作系统基础(七):Linux常见命令(二)

    文章目录 Linux常见命令(二) 一、kill命令 二、ifconfig命令 三、clear命令 四、重启与关机命令 五、which命令 六、hostname命令 七、grep命令 八、|管道 九、useradd命令 十、userdel命令 十一、tar命令 十二、su命令 十三、ps命令 作用:kill命令用于终止执行中的程序 格式: 案例: 作

    2024年02月19日
    浏览(38)
  • Linux操作基础(系统安全及应用)

    (1)将非登录用户的shell设置成/sbin/nologin (2)锁定长期不使用账号权限 (3)删除无用账号 (4)锁定账号文件psswd、shadow 通过md5sum 可以查看校验和来判断文件有没有被修改过 在新添加一个用户之后,他的校验和发生了变化。 1.21 设置密码有效期 针对新用户 在进入vim /et

    2023年04月19日
    浏览(34)
  • Linux操作系统基础教程 第一章 绪论

    第一章 绪论 一、 Unix 家族中的一员 ① UNIX , 1971 年由 ATT 发布, 73 年重写, 70 年代末, ATT 成立了 Unix 系统实验室( Unix System Lab , USL ),宣布对 Unix 产品拥有所有权, 1983 年发布了 SYSTEM V 。在 UNIX7 之前, UNIX 是免费或收取少量费 用开放源码的。 UNIX 的研发诞生了 C 语言

    2024年02月04日
    浏览(49)
  • 计算机复试面试基础知识(八股文)(数据库、数据结构、操作系统、计网、机组等)

    数据库绪论 1、简述三层模式、两级映射,分别有什么作用? 模式(逻辑模式):是数据库中全体数据的逻辑结构和特征的描述,是数据库系统模式结构的中间层,即不涉及数据的物理存储细节,也与具体应用程序开发工具语言无关。 外模式(用户模式):是用户能看见和使

    2023年04月09日
    浏览(96)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包