![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
linux操作系统
文章平均质量分 82
five丶
上海大学软工研究生,cpp后端方向
展开
-
brpc源码阅读
好久都没有更新了,最近主要在看brpc的源码,确实非常精彩,对于锁、lock-free和wait-free的策略令人拍案叫绝,下面是最近看到的一篇文章,总结的挺好,推荐给大家看看。brpc线程模型和网络模型...转载 2021-07-04 21:41:15 · 271 阅读 · 0 评论 -
c++编译过程
前言c++是一种编译型语言,在运行之前需要先经过编译器编译,虽然编译器由不同的厂家实现,但是他们需要遵守共同的规范,本文就介绍下c++的编译过程。编译的四个阶段先展示下本文实验用到的代码://main.cpp#include <stdio.h>int main(){ printf ("hello, world"); return 0;}预处理阶段预处理阶段主要处理带“#”号的文件,如#include 或#define等信息,对于include的头文件,预处理原创 2021-06-07 15:52:58 · 482 阅读 · 0 评论 -
虚拟地址空间(一)
前言准备开始更新博客了,博主是c++后端方向的,目前准备先总结下之前的知识,防止忘记,就先从Linux虚拟地址空间开始吧。一、虚拟地址空间是什么?对于32位的Linux操作系统,每个进程加载时,操作系统都会为进程分配4G的虚拟地址空间,其中包括1G的内核空间和3G的用户空间,如下图。需要说明的是,虚拟地址空间并不是真实存在于内存中的,而是对底层物理地址的封装,不同进程的虚拟地址即使相同,对应的物理地址不一定相同,这与MMU有关,我们将在后面的文章中讨论。二、用户空间和内核空间内核空间和用户空.原创 2021-04-20 11:21:25 · 318 阅读 · 1 评论 -
虚拟地址空间(二)
前言在我最开始写博客的时候,第一篇就介绍了虚拟地址空间,但当时受限于自己的水平,并且很多内容当时还没有介绍,所以当时写的比较简单,这篇文章算是还愿了吧。/proc/{pid}/mapslinux的根目录下有很多目录,比如/etc通常是存放参数文件的,/bin通常存放二进制的可执行程序,/lib通常存放库文件,/include存放头文件,/proc存放的则是进程相关的文件。对每个正在运行的文件,/proc下都有一个文件名为该进程pid号的文件夹,例如有一个pid为10086的进程正在运行,那么就存在/p原创 2021-06-06 00:38:21 · 162 阅读 · 0 评论 -
死锁条件、避免、检测和解除
什么是死锁?如果一个进程集合中的每个进程都在等待只能由此集合中的其他进程才能引发的事件,而无限期陷入僵持的局面称为死锁,例如下面的模型:此时进程A和进程B就永远处于这个状态,称进程A和进程B处于死锁状态。上述的概念换成线程也同样适用,为叙述简洁,这里就使用进程来叙述。死锁条件死锁的产生必须满足四个条件:资源互斥条件:使用资源必须是独占式地,资源本身不可分割,同一资源在某时刻至多只能被一个进程使用;请求和保持条件:进程在请求资源时,不释放目前占有的资源;不可剥夺条件:已经被某进程获取的资源在原创 2021-06-03 23:27:35 · 601 阅读 · 0 评论 -
epoll 的LT与ET实例
epoll的数据结构与函数epoll需要使用struct epoll_event 来记录需要监听的事件,将需要监听的文件描述符记录在epoll_event.data.fd中,将需要监听的事件记录在epoll_event.events中,常见的监听事件包括:EPOLLIN:读事件;EPOLLOUT:写事件;EPOLLRDHUP:读关闭事件,本端调用shutdown(SHUT_RD)或对端调用shutdown(SHUT_WR);EPOLLHUP:读写关闭事件,本端调用shutdown(SHUT_RD原创 2021-06-03 17:26:27 · 199 阅读 · 0 评论 -
五种网络IO模型
前言网络IO指的是网络通讯时,socket读取的过程,具体包括数据从硬件接口传递到内核态,再从内核态拷贝到用户态。在服务器中存在大量的网络连接,这些网络连接带来了大量的IO消耗,因此了解网络模型对我们编写服务器程序是十分必要的。阻塞式IO模型在TCP(三)中,我们给出了一个利用TCP进行client-server通信的例子,在这个例子中,server调用listen后,将等待client的连接,如果没有client连接,server将一直阻塞。这种阻塞等待IO信号的方式,被称为阻塞式IO,阻塞式IO原创 2021-06-01 00:38:16 · 87 阅读 · 0 评论 -
TCP(一)
前言TCP协议是传输层的重要协议,TCP协议保证将数据包完整、可靠地送达对端,是网络中最重要的协议之一,本文我们结合TCP的首部格式来了解TCP。TCP的首部格式TCP首部包括20bytes的固定字段和64bytes的可选字段(如下图),16位的源端口号和目的端口号是传输层的基本要求,下面我们通过这些字段来理解TCP的机制。应答TCP为每个数据包添加自增的32位序列号,在接收到数据包时,TCP也需要根据包的序列号向对端发送应答,使用client-server模型,可以通过下图来表达这个过程,其中原创 2021-05-27 21:46:38 · 239 阅读 · 0 评论 -
进程调度算法
前言在进程与线程中,我们介绍过进程的五种状态,还介绍了线程调度状态和调度算法与进程是一样的,本文我们就介绍一下常见的进程调度算法,当然按照我们之前的介绍,这些算法对线程同样适用。先来先服务(First Come First Serve)先来先服务的调度方式就和这个算法的名字一样,使用一个队列存储就绪态进程的task_struct,cpu空闲时,就从队列中取出第一个task_struct进行调度,在这个进程处理运行态时,别的进程不可抢占cpu,只能在就绪队列中等待被调度。先来先服务算法优点是很好理解,原创 2021-05-27 00:26:57 · 116 阅读 · 0 评论 -
进程间通信(三):消息队列与共享内存
前言我们在进程间通信(一)和进程间通信(二)中,我们介绍了两种传统的通信机制,本文我们介绍两种XSI进程通信机制——消息队列和共享内存。ftokXSI通信机制会在内核中创建一个IPC结构体,并使用key作为这个结构体的外部标识,ftok函数用于生成这样一个key,ftok的函数原型如下:#include <sys/ipc.h>key_t ftok(const char *path, int id); //失败返回-1path参数用于引用一个现有的文件,ftok函数按照path取原创 2021-05-21 23:49:26 · 482 阅读 · 0 评论 -
进程间通信(二):管道
前言管道是一种非常古老的进程通信机制,在目前的Linux操作系统中也随处可见,本文我们来探讨一下不同类型管道的机制和使用方法。原理在Linux文件系统(一)中我们提到过文件的类型,其中一类文件类型就是管道文件,实际上,管道的实现原理正是借助了文件系统来实现的,下图展示了管道的读写过程。读进程和写进程分别打开一个file结构体并链接到同一个i-node,通过i-node找到对应数据页进行读写。PIPEpipe被称为无名管道,是一种只能用于亲缘关系间的单工通信方法,pipe使用下面的函数创建:#原创 2021-05-20 23:23:30 · 157 阅读 · 0 评论 -
进程间通信(一):信号
前言信号是软件中断的一种,是一种较早产生的进程间通信机制,信号的名称都以“SIG”开头,比如常见的SIGABRT、SIGALRM等。信号的种类Linux中的信号被定义为正整数常量,在bits/signum.h文件中如下:#define SIGSTKFLT 16 /* Stack fault (obsolete). */#define SIGPWR 30 /* Power failure imminent. *//* Historical signals specified by POSI原创 2021-05-17 23:34:31 · 217 阅读 · 0 评论 -
Linux文件系统(二)
文件描述符与文件的关系在虚拟地址空间中,进程将打开的文件描述符放在pcb的文件描述符表中,文件描述符指向一个文件表项,文件表项则指向文件的i-node节点。i-node节点的具体结构可以参考Linux文件系统(一)中的描述,文件表项虽然是系统层面管理的,但对于相同的i-node,不同进程对应的文件表项是不同的,文件表项实际上是struct file结构体,文件描述符表就是元素为struct file的数组,同一进程中多次打开同一文件,对应的文件表项和i-node都相同,而不同进程打开同一文件,文件表项不原创 2021-05-16 14:09:52 · 88 阅读 · 0 评论 -
中断
前言中断是一种使CPU挂起正在执行的程序,转而执行其他特殊事件的操作,可以用下图形象地表示这个过程。中断的执行过程中断是通过软件和硬件配合完成的事件,在指令的执行过程中,如果处理器芯片上的中断引脚电压变高,并在总线上获取了中断向量,就会触发中断。当cpu接收了一个中断向量,cpu首先保护现场,然后通过中断向量可以在中断向量表中找到对应的中断描述符,这种中断描述符通常被称为中断门。此时cpu需要检查中断特权级,如果特权级低于当前特权级,中断将被屏蔽,反之将执行中断门指向的中断处理程序,执行完毕后恢复现原创 2021-05-13 23:23:26 · 159 阅读 · 0 评论 -
Linux文件系统(一)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档Linux有一个著名的理念:一切皆文件,在Linux中,可以把任何东西都理解为文件,这是因为Linux文件包含很多类型:普通文件,包括文本文件和二进制文件;目录文件,文件目录本身其实就是一个目录类型的文件,可以通过vim等文本编辑器直接打开,但只有操作系统内核才能直接写目录文件;块特殊文件,提供对设备(如磁盘)带缓冲的访问;字符特殊文件:提供对设备不带缓冲的访问;管道:用于进程间网络通讯的管道文件;套接字:用于进程间通讯的套接原创 2021-05-11 23:24:44 · 113 阅读 · 0 评论 -
虚拟地址与物理地址的转换
在虚拟地址空间那篇文章中我们通过虚拟地址空间简单地介绍了虚拟地址空间,知道了应用程序中使用的是虚拟地址,需要通过MMU转换成物理地址,本文将详细介绍虚拟地址如何转换成物理地址。页、页框、页表linux操作系统以页为单位管理虚拟内存,通常一页为4k,而物理内存是以块为单位管理的,物理内存被分成很多与页大小相同的块,被称为页框,每个页地址与页框对应,这种对应关系被记录在页表中,页表是MMU中的数据结构,下图是页表中较为常见的几个属性。页框存在于物理内存上,而页可以放置在任意的页框中,这是能够进行地址转原创 2021-05-10 23:34:40 · 6364 阅读 · 0 评论 -
线程同步
线程安全多线程程序共享虚拟地址空间,使得多个线程可以操作同一变量,但这也可能带来意料之外的问题,比如下面的代码:#include <bits/stdc++.h>#include <pthread.h>#include <errno.h>int num = 0;void* add(void *){ ++num; return nullptr;}int main(){ pthread_t tid[10]; for(int原创 2021-05-08 23:09:48 · 72 阅读 · 0 评论 -
进程与线程
前言我们写好的代码,通过编译后变成可执行的二进制文件,被称为程序,程序加载后被称为进程,进程中又可能包含多个线程,本文就介绍下进程和线程。进程进程是分配资源的基本单位,每个进程都有自己独立的内存空间,进程通常有5种状态,分别是:创建状态,就绪状态,等待状态,执行状态和停止状态,它们之间的转换关系如下图:进程刚创建完成时是就绪状态,此时需要等待cpu的调度,cpu调度进程后变为运行态,之后如果一直占据cpu直到时间片用完,则进入就绪态等待再次被调度,如果需要等待某事件(如鼠标键盘输入或io事件等)则原创 2021-05-07 21:34:17 · 622 阅读 · 0 评论 -
进程关系
终端登录linux系统启动时,内核创建ID为1的init进程,当有新用户登录时,如果终端允许登录,init进程fork出子进程,然后使用exec装载getty程序,getty程序具有超级用户权限,使用RW方式打开终端,此时将会设置文件描述符0、1、2,并等待用户输入账户登录,用户输入账户名后,进程使用exec装载login程序。login程序此时仍拥有超级用户权限,等待用户输入正确密码后,设置当前目录,终端所有权、访问权限、组ID、用户ID等信息,这些信息之前被记录在/etc/passwd中,如果多次输原创 2021-05-05 23:16:27 · 72 阅读 · 0 评论 -
fork/vfork
前言unix操作系统提供了一系列进程的控制原语来操作进程,fork()/vfork()就是其中用于创建新进程的两种系统调用。forkfork()函数创建的新的子进程是原本父进程的副本,从虚拟地址空间的角度来看,可以用下图表示。此时的子进程几乎和父进程一摸一样,包括代码的执行位置。fork()函数在unistd.h文件中声明,下面是函数原型:pid_t fork();pid_t是进程id的类型,fork()失败时,返回值为-1,fork()成功时,父进程返回子进程的进程id,子进程返回0。下面原创 2021-05-04 00:52:09 · 91 阅读 · 0 评论 -
exec函数族
这个系列是新开的apue阅读笔记系列。前言unix操作系统下,经常使用fork来创建子进程,而fork创建的子进程是完全复刻父进程的映像,如果我们想要执行另一个程序,可以使用exec函数族中的某个函数替换执行的程序,exec函数族成员exec函数族总共包含七个函数,他们都定义在unistd.h文件中,他们执行出错时均返回-1。#include <unistd.h>int execl(const char *pathname, const char *arg0,.../* (char原创 2021-05-03 14:20:16 · 88 阅读 · 0 评论