Linux
文章平均质量分 76
Ch_ty
这个作者很懒,什么都没留下…
展开
-
不一样的hello world
一. 简介 最近学习了一些C内联汇编的知识,简单的尝试了一下,发现里面有很多有趣的东西,分享如下。首先说明,本文的内联使用仅为一个小例子,并不规范,另外32位和64位有着较大区别,本文基于64位Ubuntu16.04环境编译。二. 源码介绍 代码本身很简单,包括了三个函数,分别用于打印,退出以及作为函数入口,实际效果为输出Hello world。2.1 print() 打印函数printf()本身其实是调用了write()函数(也可以调用puts()等),这里通过80中断直接调用write(原创 2021-02-01 19:06:36 · 150 阅读 · 0 评论 -
Linux操作系统学习笔记(三十)docker和k8s的恩怨情仇
一. 简介 之前聊天发现很多小伙伴对docker和k8s了解甚少,所以决定分享一下在docker和k8s背后这些年容器发展的故事,谈不上以史为鉴,但是至少可以从中汲取经验教训,同时也能了解容器及容器编排发展的来龙去脉。二.PaaS和容器 让我们把话题稍稍往前拖一点。在2013年前后,云计算技术已经较为普及,如AWS和盛极一时的OpenStack。而在此时,PasS的观念逐渐深入人心。如下图所示,橙色代表用户自己需要承担的工作,而绿色代表第三方提供的服务,从左到右分别为:自建软件:自己完成所有的原创 2021-02-01 19:05:40 · 588 阅读 · 0 评论 -
Linux操作系统学习笔记(二十九)深入理解存储器
一. 前言 本文延续上文介绍CPU的基本思路,继续探索计算机的存储器,包括寄存器、CPU缓存、内存和硬盘,在深入了解存储器的基础上,我们可以写出性能更为优异的代码。二. 存储分级 存储分级的根本原因还是性价比,即性能和价格的权衡。最快的当然是SRAM(Static Random-Access Memory,静态随机存取存储器),但是其密度较低、存储数据有限、价格偏高。而DRAM(Dynamic Random Access Memory,动态随机存取存储器)的芯片,比起 SRAM 来说,它的密度更高原创 2021-01-18 22:01:56 · 407 阅读 · 0 评论 -
Linux操作系统学习笔记(二十八)深入理解CPU
一. 前言 在前面一些文章中多多少少有提到一些CPU的结构以及对应的寄存器等,但是总觉得不够透彻,所以单开一文详细叙述CPU的各种知识,从而加深对操作系统和性能的理解。本文从最基本的加法器和乘法器切入,随后介绍CPU的基本架构和实现原理,接着介绍各个核心模块的实现细节,最后介绍CPU的一些高级黑科技。二. 加法器和乘法器2.1 门电路和半加器 如果从二极管如何形成高低电平说起,那怕是要说完大部分《模拟电路设计》和《数字电路设计》的知识了,有兴趣的同学可以回顾一下自行研究,我们就从各种基本门电路原创 2021-01-18 22:00:53 · 1833 阅读 · 0 评论 -
关于GDB运行时No symbol table is loaded. Use the “file“ command.的解决方法
最近有同学问GDB使用的问题,对此做一个整理。首先,GDB已经报错file找不到了,那可以运行file test检测一下(gdb) file testReading symbols from test...(no debugging symbols found)...done.发现找不到可执行文件,所以问题应该在于编译时候没有加上ggdb3,重新编译一下ty@ubuntu:~$ gcc -ggdb3 -o main main.c编译完成再次执行就没有问题了,问题解决。..原创 2020-12-19 22:27:32 · 5410 阅读 · 2 评论 -
Linux操作系统学习笔记(二十七)磁盘I/O性能优化
一. 前言 本文是性能优化系列的最后一篇,将分析磁盘I/O的性能指标、测试方法、常见问题的优化套路等内容。二. I/O性能指标及查询工具 磁盘性能的衡量标准经常用到的包括使用率、饱和度、IOPS、吞吐量以及响应时间等。这五个指标是衡量磁盘性能的基本指标。使用率,是指磁盘处理 I/O 的时间百分比。过高的使用率(比如超过 80%),通常意味着磁盘 I/O 存在性能瓶颈。饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受原创 2020-12-07 22:03:50 · 939 阅读 · 0 评论 -
Linux操作系统学习笔记(二十六)内存性能优化
一. 前言 本文将分析内存的性能指标、测试方法、压测工具以及内存常见问题的优化套路。二. Buffer和Cache 通过free或者top命令我们可以发现其将内存分为了buffer和cache等部分。Buffer 和 Cache 的设计目的,是为了提升系统的 I/O 性能。它们利用内存,充当起慢速磁盘与快速 CPU 之间的桥梁,可以加速 I/O 的访问速度。通过man free可以查阅到下面的说明buffers Memory used by kernel buffers (Buffers原创 2020-12-07 22:01:56 · 391 阅读 · 1 评论 -
Linux操作系统学习笔记(二十五)CPU性能优化
一. 前言 本文介绍Linux服务器CPU性能评估和优化的基本方法。二. CPU性能查询工具详解2.1 平均负载 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常原创 2020-11-30 12:54:37 · 1112 阅读 · 0 评论 -
Linux操作系统学习笔记(二十四)网络通信之性能优化
一. 前言 在前面的几篇文章中,我们大致介绍了Linux网络协议栈的基本结构体、收发流程、TCP协议设计原理等,整个网络通信其实是一个很复杂的过程。本文介绍性能测试、性能评估、性能优化等方方面面的基本内容和大致优化思路。二. 总体性能参数和工具 对于服务器来说,首先需要一个大致的轮廓来描述其性能,这些性能参数将整个应用视为黑盒,测试其从外部看上去的性能表现,属于第一步需要掌握的数据。只有先掌握了这些数据后,后续的分析才有意义。带宽:表示链路的最大传输速率,单位通常为 b/s (比特 / 秒)原创 2020-11-30 12:53:33 · 1838 阅读 · 0 评论 -
Linux操作系统学习笔记(二十三)网络通信之收包
一. 简介 本文将分析网络协议栈收包的整个流程,收包和发包是刚好相反的过程。根据顺序我们将依次介绍硬件设备驱动层、数据链路层、网络层、传输层、套接字文件系统的相关发包处理流程,内容较多较复杂,主要掌握整个流程即可。二. 网卡驱动层 网卡作为一个硬件,接收到网络包后靠中断来通知操作系统。但是这里有个问题:网络包的到来往往是很难预期的。网络吞吐量比较大的时候,网络包的到达会十分频繁。这个时候,如果非常频繁地去触发中断,会造成频繁的上下文切换,带来极大的开销。因此硬件处理厂商设计了一种机制,就是当一些原创 2020-11-30 12:52:17 · 879 阅读 · 0 评论 -
volatile硬核剖析
一. 前言 volatile在JAVA和C/C++中均有使用,而含义不同。不论是前者还是后者,在网上都流传着诸多误解,为此我们抛开一切中文资料,从JAVA、C/C++的文档手册、开发者的博客、stack overflow的高赞问题回复等源头去着手了解,并结合实际代码测试来验证其说法的可靠性。二. JAVA的volatile 首先来看一个来自于DZone社区的例子public class VolatileTest { private static final Logger LOGGER =原创 2020-11-23 21:20:19 · 257 阅读 · 0 评论 -
Linux操作系统学习笔记(二十二)网络通信之发包
一. 简介 本文将分析网络协议栈发包的整个流程,根据顺序我们将依次介绍套接字文件系统、传输层、网络层、数据链路层、硬件设备层的相关发包处理流程,内容较多较复杂,主要掌握整个流程即可。二. 套接字文件系统 在前文中已经介绍了套接字socket和文件描述符fd以及对应的文件file的关系。在用户态使用网络编程的时候,我们可以采用write()和read()的方式通过文件描述符写入。套接字文件系统的操作定义如下,读对应的是sock_read_iter(),写对应的是sock_read_iter()s原创 2020-11-23 21:19:36 · 1333 阅读 · 0 评论 -
关于sysctl同时修改多项参数的方法
在进行Linux系统优化的时候经常会用到sysctl查看以及调整内核参数,如$ sysctl net.ipv4.tcp_wmemnet.ipv4.tcp_rmem = 4096 87380 2756608 对于这种多参数的情况下,我们需要扩上双引号进行修改,如下所示$ sysctl -w net.ipv4.tcp_wmem="XXXX XXXX XXXX"$ sysctl -p 这样才可以正常生效。...原创 2020-10-10 20:45:47 · 462 阅读 · 0 评论 -
Linux操作系统学习笔记(十九)网络通信之套接字
一. 前言 在前面我们逐一分析了进程间通信的各种方法:信号,管道,共享内存和信号量,本文开始将分析更为复杂也是更为常用的另一套进程间通信:网络通信。网络通信和其他进程间通信最大的区别在于不局限于单机,因此成为了互联网时代的主流选择,无论是分布式、云计算、微服务、容器及自动化运营都离不开网络通信,其重要性可想而知。 经过30多年的发展,网络协议栈已经变得极为复杂,远远不是一两篇文章能够说清楚的东西,所以这里着重剖析我们更为关注的东西:网络编程涉及到的相关协议栈。从本文开始,将分别介绍套接字及其创建、网原创 2020-09-19 12:31:34 · 606 阅读 · 0 评论 -
Linux操作系统学习笔记(十八)进程间通信之共享内存和信号量
一. 前言 本文为进程间通信的最后一篇,介绍共享内存和信号量。之所以将二者一起叙述,是因为二者有着密不可分的关系。共享内存会利用虚拟内存和物理内存的映射关系,让不同进程开辟一块虚拟空间映射到相同的物理内存上,从而实现了两个进程对相同区域的读写,即进程间通信。而信号量则实现了互斥锁,可以为共享内存提供数据一致性的保证,因此二者常结合使用。二. 基础知识 共享内存的使用包括调用shmget()创建共享内存调用shmat()映射共享内存至进程虚拟空间调用shmdt()接触映射关系 信号量原创 2020-09-19 12:30:38 · 1482 阅读 · 0 评论 -
Linux操作系统学习笔记(十七)进程间通信之管道
一. 前言 上文中我们介绍了进程间通信的方法之一:信号,本文将继续介绍另一种进程间通信的方法,即管道。管道是Linux中使用shell经常用到的一个技术,本文将深入剖析管道的实现和运行逻辑。二. 管道简介 在Linux的日常使用中,我们常常会用到管道,如下所示ps -ef | grep 关键字 | awk '{print $2}' | xargs kill -9 这里面的竖线|就是一个管道。它会将前一个命令的输出,作为后一个命令的输入。从管道的这个名称可以看出来,管道是一种单向传输数据的原创 2020-08-30 12:14:51 · 595 阅读 · 0 评论 -
Linux操作系统学习笔记(十六)进程间通信之信号
一. 前言 众所周知,System V IPC进程间通信机制体系中有着多种多样的进程间通信方式,如管道和有名管道,消息队列,信号,共享内存和信号量,套接字。从本文开始我们就逐个剖析进程间通信的机制和底层原理,就从信号开始讲起吧。二. 信号基本知识 信号是进程处理紧急情况所用的一种方式,它没有特别复杂的数据结构,就是用一个代号一样的数字。Linux 提供了几十种信号,分别代表不同的意义。我们可以通过kill -l命令查看信号。# kill -l 1) SIGHUP 2) SIGIN原创 2020-08-30 12:13:57 · 641 阅读 · 0 评论 -
Linux操作系统学习笔记(十五)中断
一. 前言 在前面的文章里,我们多次见到了中断的作用,如任务调度,系统调用从用户态陷入内核,文件系统的读写操作等。本文就Linux的中断机制进行较为全面的剖析。二. 什么是中断 中断通常被定义为改变处理器执行指令的顺序的一个事件,该事件与CPU芯片内外部硬件电路产生的电信号相对应。中断通常分为同步中断和异步中断:同步中断(synchronous):又称异常(exception),在指令执行时由CPU控制单元产生,之所以称之为同步,是因为只有在一条指令终止执行后CPU才会发出中断。异步中断(原创 2020-08-30 12:13:01 · 760 阅读 · 0 评论 -
Linux操作系统学习笔记(十四)块设备
一. 前言 上文我们分析了字符设备,本文接着分析块设备。我们首先分析块设备的基本结构体,然后分析块设备生成、加载的整个过程,最后分析块设备的直接I/O访问和缓存I/O访问。二. 块设备基本结构体 上文中我们分析了字符设备驱动程序的抽象结构体cdev和管理cdev的结构体cdev_map,在块设备中会相对复杂一些,因为涉及到一个概念:伪文件系统bdevfs。在此之下主要有三个结构体:对块设备或设备分区的抽象结构体block_device,对磁盘的通用描述gendisk以及磁盘分区描述hd_struc原创 2020-08-21 22:12:30 · 4224 阅读 · 0 评论 -
Linux操作系统学习笔记(十三)字符设备
一. 前言 上文中我们分析了虚拟文件系统的结构以及常见的文件操作从用户态到虚拟文件系统再到底层实际文件系统的过程。而实际上我们并没有说明实际的文件系统如ext4是如何和磁盘进行交互的,这就是本文和下篇文章的重点:I/O之块设备和字符设备。输入输出设备我们大致可以分为两类:块设备(Block Device)和字符设备(Character Device)。块设备将信息存储在固定大小的块中,每个块都有自己的地址。如硬盘就是常见的块设备。字符设备发送或接收的是字节流,而不用考虑任何块结构,没有办法寻原创 2020-08-17 13:04:56 · 1132 阅读 · 0 评论 -
Linux操作系统学习笔记(十二)虚拟文件系统
一. 前言 基于上文介绍的文件系统的基本结构,本文将继续深入Linux文件系统的精髓所在:虚拟文件系统。操作文件的本质是将磁盘文件数据映射到进程中,上文的文件系统是如何存储文件数据,而从进程如何映射到该文件系统,中间还有一系列的过程,主要包括进程发出文件操作命令,通过系统调用如sys_open、sys_read、sys_write调用相应内核函数在内核中为进程打开的文件和系统文件创建数据结构进行维护通过虚拟文件系统对各种不同的文件系统操作,如I/O设备、管道、进程间通信、网络等进行抽象并统一接口原创 2020-07-31 12:28:12 · 1116 阅读 · 0 评论 -
Linux操作系统学习笔记(十一)文件系统
一. 前言 本节开始将分析Linux的文件系统。Linux一切皆文件的思想可谓众所周知,而其文件系统又是字符设备、块设备、管道、进程间通信、网络等等的必备知识,因此其重要性可想而知。本文将先介绍文件系统基础知识,然后介绍最重要的结构体inode以及构建于其上的一层层的文件系统。二. 文件系统基础知识 一切设计均是为了实现需求,因此我们从文件系统需要的基本功能来看看其该如何设计。首先,一个文件系统需要有以下基本要求文件需要让人易于读写,并避免名字冲突等文件需要易于查找、整理归类操作系统需要原创 2020-07-31 12:27:30 · 499 阅读 · 0 评论 -
Linux操作系统学习笔记(八)任务空间管理
一. 前言 从本文开始,我们进入内存部分的学习。首先会接着前面的任务task_struct讲解任务空间管理结构体mm_struct,并简单介绍物理内存和虚拟内存的相关知识,关于详细的基础知识和概念可以参照CSAPP一书,这里不会做过多的赘述,而是默认在已了解其映射关系的基础上进行的学习。在后文中,会继续介绍物理内存的管理以及用户态和内核态的内存映射。二. 基本概念梳理CPU、缓存、内存、主存的架构是源于越快的设备越贵,因此出于节约(qiong)考虑设计了多层架构,CPU中有了MMU物理内存有限,原创 2020-06-25 17:42:38 · 741 阅读 · 0 评论 -
Linux操作系统学习笔记(七)任务调度
一. 前言 在前文中,我们分析了内核中进程和线程的统一结构体task_struct,并分析进程、线程的创建和派生的过程。在本文中,我们会对任务间调度进行详细剖析,了解其原理和整个执行过程。由此,进程、线程部分的大体框架就算是介绍完了。本节主要分为三个部分:Linux内核中常见的调度策略,调度的基本结构体以及调度发生的整个流程。下面将详细展开说明。二. 调度策略 Linux的调度策略主要分为实时任务和普通任务。实时任务需求尽快返回结果,而普通任务则没有较高的要求。在前文中我们提到了task_str原创 2020-06-13 11:28:38 · 1459 阅读 · 0 评论 -
Linux操作系统学习笔记(六)进程、线程的创建和派生
一. 前言 在前文中,我们分析了内核中进程和线程的统一结构体task_struct,本文将继续分析进程、线程的创建和派生的过程。首先介绍如何将一个程序编辑为执行文件最后成为进程执行,然后会介绍线程的执行,最后会分析如何通过已有的进程、线程实现多进程、多线程。因为进程和线程有诸多相似之处,也有一些不同之处,因此本文会对比进程和线程来加深理解和记忆。二. 进程的创建 以C语言为例,我们在Linux下编写C语言代码,然后通过gcc编译和链接生成可执行文件后直接执行即可完成一个进程的创建和工作。下面将详细原创 2020-06-13 11:26:39 · 1021 阅读 · 0 评论 -
Linux操作系统学习笔记(二)内核运行
前言 上文中,我们分析了从按下电源键到BootLoader完成加载的过程。加载完成之后,就要正式启动Linux内核了,而在这之前首先要完成从实模式到保护模式的切换。本文主要分析以下几部分内容新旧中断的交替打开A20进入main函数内核初始化 其实整个过程中还有很多内容,比如检查各种硬件设备等,在此略过不提。下面就开始潜入Linux源码的海洋畅游啦。新旧中断的交替 在实模...原创 2020-05-09 11:05:54 · 891 阅读 · 0 评论 -
Linux操作系统学习笔记(一)启动
前言 Linux操作系统内核是服务端学习的根基,也是提高编程能力、源码阅读能力和进阶知识学习能力的重要部分,本文开始将记录Linux操作系统中的各个部分源码学习历程。 关于如何学习源码,个人觉得可以从以下角度入手,有效地提高阅读和学习的效率。(学习语言就不说了,这是基本功。学习IDE推荐Source Insight或者Visual Studio)理解代码的组织结构。 以Linux源码举...原创 2020-05-01 17:45:20 · 582 阅读 · 0 评论 -
string处理工具函数小结
本文总结实际开发过程中用到的string类的处理工具函数的总结,如下所示:#include <array>#include "string_util.h"std::string combine_path(std::string const& lhs, std::string const& rhs){ ASSERT(!is_complete(rhs...原创 2020-03-22 11:07:18 · 218 阅读 · 0 评论 -
C++利用SIO_GET_INTERFACE_LIST查询网关
网关原创 2020-03-14 11:42:32 · 445 阅读 · 0 评论 -
关于std::unsorted_map和std::map
| map | unordered_mapOrdering | increasing order | no ordering| (by default) |Implementation | Self balancing BST | Hash Table| like Red-Black Tree |search time ...原创 2020-01-22 21:30:10 · 1880 阅读 · 0 评论 -
关于std::shared_ptr和enable_share_from_this的一个隐蔽的问题
使用共享指针的时候,采用thi传递可能会出现异常析构局部变量的问题,这里采用enable_shared_from_this可以解决原创 2020-01-09 21:39:16 · 290 阅读 · 0 评论 -
关于boost和std库转换的一些经验
本文记录boost库和std库转换过程中遇到的一些困难和解决方法。tuple除了需要包含tuple还需要包含functional文件boost::function实际就是函数指针的封装boost::intrusive_ptr就是共享指针std::shared_ptrboost::pool用于内存管理,目前没有合适的std库替换boost的变量类型可以替换为vc++自带的udp::...原创 2019-11-17 21:27:44 · 1423 阅读 · 0 评论 -
offset of 和 container of 解析
在Linux源码中,经常看到大名鼎鼎offset of 和 container of 的宏定义,这里就此进行解析,并做了实验验证用途,仅用于自己参考记录。原创 2018-05-31 22:37:00 · 1364 阅读 · 3 评论 -
异步OpenSSL实现HTTPS心得
本文记录在使用OpenSSL实现异步式HTTPS中的一些心得体会。1.关于握手(1)如果没有使用封装库,可以得到套接字描述符;而且非异步系统,允许握手的阻塞,则直接使用API将套接字和OpenSSL绑定,从而完成SSL握手绝对是明智之选,可以省下很多麻烦。(2)如果封装之后得不到套接字描述符,或者要求异步非阻塞,那么使用SSL_SET_CONNECT配合SSL_read,再用SSL...原创 2018-08-06 22:08:21 · 3884 阅读 · 0 评论 -
关于sizeof 和 strlen深坑全解析
一. 前言 大家都知道,sizeof和strlen可以用来获取大小,但是有着不同的用法,这里首先总结区别,最后根据sizeof 和 strlen 的具体事例来分析特别需要注意的事项。二. sizeof 和 strlen 的特点、区别 二者的区别是老生常谈的话题,也不是本文的重点。这里直接放上总结:1.sizeofsizeof是操作符,strlen是函数。 操作符的结果类型是size_t...原创 2019-01-12 16:20:44 · 423 阅读 · 0 评论 -
简述strcmp/strncmp比较失败的问题
一. 前言 在最近写代码中,遇到了strcmp/strncmp比较失败的问题,由此引出此文的讨论分析。二. 分析 首先看看strcmp的源码:int strcmp ( const char* src, const char* dst ){ int ret = 0 ; while( !(ret = *(unsigned char *)src - *(unsigned char *)...原创 2019-01-13 17:01:26 · 4491 阅读 · 0 评论 -
网络通信中数字的转换
在网络通信中,经常用到需要保存结构体的一些数字,到另一端获取之后读取出来,这里给出一种转换为十六进制字符串的方法保存并读取。#include <iostream>struct peer_request{ // the index of the piece in which the range starts. int piece; // the offset withi...原创 2019-02-22 20:37:11 · 282 阅读 · 0 评论 -
libutp收发机制分析
一. 前言 本文旨在通过libutp收发部分源码的分析了解libutp内部的实现机制。二. 基本结构体 无论是了解源码还是使用libutp,都离不开libutp的两个基本结构体:typedef struct UTPSocket utp_socket;typedef struct struct_utp_context utp_context;utp_socket和utp...原创 2019-03-09 21:31:49 · 455 阅读 · 0 评论 -
结构体字节对齐的问题
最近在使用udp传输结构体的时候,发现了一个问题:结构体的实际大小和预想的并不一样,例子如下:struct msg{ int index; int length; char id; int start;};如上所示的结构体中,预估大小为4 * 3 + 1 = 13 字节,但是实际上使用sizeof函数得到结果是16。通过wireshark抓包发现实际上存在一个字节对齐的问题:...原创 2019-04-02 18:51:32 · 324 阅读 · 0 评论 -
vc++实现组播传输
组播传输比起普通udp传输主要多了加入组以及设置本地回环是否接收等设定。需要注意的是,如果本地有多个IP,绑定local address的时候建议不要使用INADDR_ANY。源码如下#include <iostream>#include <winsock2.h> #include <Ws2tcpip.h>#include <process.h......原创 2019-04-11 22:12:20 · 2883 阅读 · 0 评论