操作系统与Linux
文章平均质量分 95
Linux和一些通用的OS知识。
ka__ka__
软件工程师
展开
-
一个极简操作系统的代码实现
在网上看的demo OS实现时,发现一个名为`Hurlex`的demo OS project,实现精简,麻雀虽小五脏俱全,挺适合对OS实现进行代码级别的快速粗略了解一下的。当然,高校也有类似的很不错的教学项目,比如`MIT Xv6 OS`, `哈工大李治军Linux-0.11 OS实验`,这些有更加详细的配套文档和项目代码,更加适合深入的学习。上面的demo OS都可以通过QEMU仿真器直接跑起来并且能调试。原创 2023-06-04 23:29:19 · 453 阅读 · 0 评论 -
使用QEMU调试ARM64 Linux内核v6.0.9
本文主要介绍如何使用QEMU调试最新的ARM64内核。用到的工具都从源码编译,QEMU编译,根文件系统制作,GDB调试ARM64的linux内核,都有一个基本的介绍。原创 2022-11-19 16:55:57 · 2517 阅读 · 0 评论 -
Linux shell脚本引用类似include其他脚本的方法
Shell 脚本规模大了总会比较难维护,但是很多时候又得必须用。适当的拆分文件的方法挺好,Shell脚本没有include或者import机制,查了资料就是用source命令来解决。一个小例子:test.sh#!/bin/bashsource add.shadd 1 2add.sh#!/bin/bashecho "this is $0"add() { echo $...原创 2019-11-29 22:15:45 · 2967 阅读 · 0 评论 -
Linux 文件描述符解析
关键数据结构在现代操作系统抽象中,进程是资源管理的最小单位,线程是CPU调度的最小单位。Linux有着“一切皆文件”的说法,很大的原因就是文件描述符这个强大的抽象,为I/O操作提供了一个统一的数据结构和接口。内核维护的3个数据结构:进程级的文件描述符表(descriptor table),每个进程都有自己独立的文件描述符表,主要包含了是:控制标志(flags)和指向打开文件表象的指针。POSIX标原创 2017-08-14 00:31:17 · 612 阅读 · 0 评论 -
Linux 多线程 pthread库初探
Linux 多线程 pthread库用法(一)Linux 多线程编程基介绍Linux 线程有时候也叫 Light Weight Process LWP 轻量级线程,是进程的一个执行流,有自己的执行栈,是操作系统调度的最小单位。 多线程优势在于切换开销小,同进程内通信方便,涉及IO等阻塞性操作时可以单独开一个线程不阻塞主流程,不足之处健壮性不如多进程,一个线程crash,那么所在进程就都...原创 2016-04-19 23:54:10 · 3129 阅读 · 0 评论 -
Linux C函数调用栈帧结构
Linux C程序的反汇编,每个函数第一个指令都是push %rbp,即当caller者调callee时,指令callq <fun addr> callee返回后的下一个指令地址压入栈帧,然后push %rbp 保存 rbp寄存器,紧接着mov %rsp,%rbp 更新rbp 寄存器这样层层调用构成函数调用栈,每个栈帧开始就是存的上一个栈帧的rbp, 结尾就是调用callee后的下一个...原创 2017-04-25 23:06:23 · 2524 阅读 · 0 评论 -
Go语言模型:Linux线程调度 vs Goroutine调度
调度本质上体现了对CPU资源的抢占。调度的方式可以分为:抢占式调度。依赖的是中断机制,通过中断抢回CPU执行权限然后进行调度,如Linux内核对线程的调度。协作式调度。需要主动让出CPU,调用调度代码进行调度,如协程,没有中断机制一般无法真正做到抢占。Linux NPTL 线程库看操作系统方面的文章时,要注意区分其描述的是通用操作系统还是某种特定的操作系统(如: Windows/...原创 2019-01-31 23:10:42 · 2224 阅读 · 0 评论 -
Linux IPC: UNIX Domain Socket 基本用法
当前Linux IPC最常用的方法就是UNIX Domain Socket和TCP Socket了。使用TCP Socket可以看:Linux Socket TCP通信基本用法。这两种IPC一个很大的区别就是:TCP使用IP + Port来标记进程;UNIX Domain Socket使用文件来标记进程;由于上面差异,在socket API标记地址的结构体也有所不同,Domain S...原创 2018-06-27 00:21:01 · 2495 阅读 · 0 评论 -
Linux C/C++定时器的实现原理和使用方法
定时器的实现依赖的是CPU时钟中断,时钟中断的精度就决定定时器精度的极限。一个时钟中断源如何实现多个定时器呢?对于内核,简单来说就是用特定的数据结构管理众多的定时器,在时钟中断处理中判断哪些定时器超时,然后执行超时处理动作。用户空间程序不直接感知CPU时钟中断,感知内核的信号、IO事件、调度,间接依赖时钟中断。软件实现动态定时器常用数据结构有:时间轮、最小堆和红黑树。原创 2018-07-16 22:55:49 · 36471 阅读 · 4 评论 -
Linux网络编程:基于epoll的IO多路复用并发模型
Linux网络编程用的比较多的就是基于epoll的IO多路复用模型。高性能Web服务器Nginx底层使用的就是epoll。常见的并发模型对比多线程模型多线程并发模型一般使用同步IO,每个连接起一个线程,编程相对直观容易,但是连接数非常受限,在IO密集型场景吞吐量就比较低。一台计算机同时可以执行的线程取决于CPU核数,即使开了CPU超线程,也并不会增加多少可以真正并发的线程。而且,每个线程都需...原创 2018-12-09 00:05:27 · 1262 阅读 · 2 评论 -
x64 ASM 常用汇编指令
语法习惯立即数,$ 开头寄存器,% 开头取地址里面的值,偏移量(%寄存器)// 除了 lea 取地址指令)外,lea就是取地址 load effecive address整形操作通用后缀,后缀 [b w l q 1 2 4 8] byte word l… quadruple, 表示多少字节浮点指令还有三个 [s d t 4 8 16] single double extended (修饰精原创 2019-08-28 23:51:59 · 26546 阅读 · 2 评论 -
Linux C pthread多线程,join和detach
Linux C多线程使用,有一个注意点需要注意,新启动的子线程一定要在主线程join,或者本身被设置为detach,否则会引起资源泄露,如每个线程都有自己的运行stack,内核中的task_stuct数据结够等。正如,父子进程中的子进程退出没有被父进程join就会变成僵尸进程一样。一个例子,最终会导致资源耗尽 pthread_create 返回 11. 这个错误是 EAGAIN 的意思就是操作系...原创 2019-09-18 23:39:47 · 1253 阅读 · 0 评论 -
操作系统原理:进程地址空间
Linux进程虚拟存储先回忆一下ELF文件的组织结构,可以看这篇文章:Linux 链接与ELF文件。程序执行后进程地址空间布局则和操作系统密切相关。在将应用程序加载到内存空间执行时,操作系统负责代码段与数据段的加载,并在内存中为这些段分配空间。Linux的进程地址空间大致如下:Linux内核虚拟存储内核虚拟存储器包含了内核的代码和数据结构。内核虚拟存储器的一些区域被映射到所有进...原创 2017-03-07 00:17:39 · 3522 阅读 · 0 评论 -
Linux网络编程:TCP Socket通信的基本用法
从 TCP/IP 协议说起通信必然要求参与通信的双方约定好规则,这就是协议。当今世界的互联网基本就是跑在 TCP/IP 协议族上。两台主机通信最底层就是网卡对外发送的以太网帧。下面从报文结构的角度从底向上说说协议: 以太帧头, 以太头有本对端MAC地址,主要 用来二层交换, MAC地址是固化在网卡中的,一个主机可以插多个网卡。IP头, 有本对端IP地址,主要用来路由,一个网卡可以配多...原创 2016-05-30 00:29:52 · 1624 阅读 · 0 评论 -
Linux IPC 共享内存基本用法
Linux IPC 常见的方式写 Linux Server 端程序,必然会涉及到进程间通信 IPC. 通信必然伴随着同步机制,下面是一些常见的通信与同步机制:进程间通信:匿名管道,命名管道,消息队列,共享内存,Domain Socket, 本机 TCP Socket,文件进程间同步:信号,信号量线程间同步:条件变量,互斥量,读写锁,自旋锁,Barrier.对于大部分的业务场景,本机 TCP原创 2016-05-08 23:55:30 · 1883 阅读 · 0 评论 -
Linux 同步机制:互斥量
互斥锁互斥锁也叫互斥量,也是Linux的一种同步机制。互斥锁相比信号量增加了所有权的概念,被锁的互斥量只能由给它上锁的线程解开,而信号量则无此限制。信号量侧重在资源的数量,可用来实现按一定逻辑调度线程。互斥量则就是纯粹的保护共享资源,不被并发访问,用起来也更加的简单。对于可以用互斥量解决的场景,就不要用信号量。举例下面是典型的生产者消费者例子,读写过程做到原子操作。原创 2016-12-26 23:59:20 · 574 阅读 · 0 评论 -
Linux 同步机制:读写锁
读写锁 读共享写独占读写锁也叫 shared-exclusive 锁, 也是一种同步机制。读写锁有三种状态:读模式下加锁,写模式下加锁,不加锁。有如下的使用约定:不加锁或者读模式加锁状态时,任何线程都可以读模式枷锁,但是写模式加锁会被阻塞;不加锁状态时,才可以进行写模式加锁;读模式加锁状态时,有线程进行写加锁,读写锁会阻塞后面的读加锁,防止试图进行写加锁的线程由于得不到锁而长期阻塞;读模式共原创 2017-01-04 21:48:54 · 792 阅读 · 0 评论 -
Linux 同步机制:条件变量
条件变量的优势条件变量提供了一种线程间的通知机制,达到条件唤醒对应线程,配合互斥量,可以解决多线程中大多数的同步问题。需要信号量的解决问题的基本都可以用条件变量加互斥量解决。由于信号量使用起来容易出错,实际工程中用互斥量和条件变量的更多。互斥量可以保护共享数据的原子访问,但是无法很好的保证条件时序,单纯的配合sleep调用的忙等待会浪费CPU,也无法做到第一时间感知到条件ok。这里配合条件变量就可以原创 2017-01-13 00:15:34 · 1085 阅读 · 0 评论 -
Linux 同步机制:自旋锁
自旋锁的特点与适用场景Linux自旋锁spinlock同一时刻只能被一个可执行线程持有。当一个线程试图获取一个已经被持有的spin lock时,就会一直忙循环-选择-等待锁重新可用。忙等待免去了线程挂起再被唤醒的转换,省去了两次上下文切换的时间。因而spinlock适合下面的场景:SMP多核系统中,持有自旋锁的时间小于完成两次上下文切换的时间,这种场景使用spinlock效率会比较高。所以一般在用户原创 2017-01-17 23:29:38 · 1700 阅读 · 0 评论 -
Linux 文件IO: 缓冲与非缓冲
本地普通文件IO一般都是同步阻塞的本地普通文件IO一般关注的是缓存,一般都是同步阻塞的。普通文件的file descriptor是block也是POSIX标准的。这点不同于网络IO,网络IO要考虑传输两边进程处理等,设计之初就提供了带状态检测的异步操作方式,本地文件IO则必然要求高可靠性的。利用系统调用, unbuffered I/O不带缓冲指的是每个read和write都调用了内核的一个系统调用。原创 2016-11-27 12:14:29 · 2575 阅读 · 1 评论 -
Linux 网络IO: 同步、异步、阻塞与非阻塞
对于Linux,当前主流的网络I/O还是同步I/O,对于处理高并发,采用的方案就是I/O复用,多线程,多进程。具体选择要根据业务场景的特点来选择。同步、异步和阻塞、非阻塞针对的是两个不同的维度:同步的关键是有序,强调的有序的任务序列,下一步操作依赖这一步。异步的关键是处理调用的对象在处理完成后主动通知,可通过回调,通知,状态变更等,依赖具体的实现机制。这里的机制很关键,CPU调度的最小...原创 2016-11-23 00:11:19 · 1028 阅读 · 0 评论 -
操作系统原理:动态内存分配
动态内存分配背后的机制深刻的体现了计算机科学中的这句名言: All problem in CS can be solved by another level of indirection. — Butler Lampson ...原创 2017-04-12 23:21:13 · 5772 阅读 · 0 评论 -
操作系统原理:虚拟地址
The Memory Hierarchy存储系统是有层次的,从快到慢依次是:CPU寄存器、静态SRAM、动态DRAM、磁盘。如下图: 如 Inter Core i7 存储结构如下: i7的存储架构支持48-bit虚拟地址,52-bit物理地址. Page Size启动时可配置 4KB or 4MB, Linux使用4KB,4-level page table hierarchy。...原创 2017-02-23 00:54:27 · 3911 阅读 · 0 评论 -
操作系统原理:链接与ELF文件
ELF文件本文主要针对Linux系统。在x86架构下,Linux使用的是ELF(Executable and Linkable Format)目标文件格式。目标文件的三种格式:Relocatable object file. 可重定位目标文件包含二进制代码和数据,编译时可与其他可重定位目标文件合并组成可执行目标文件,如 .o,.a文件。Executable object file. 可...原创 2017-02-05 17:06:18 · 2724 阅读 · 0 评论 -
从汇编角度看Linux C函数的调用约定和参数传递的细节
x86架构下,函数执行借助于 hardware stack。为了不同模块函数能在runtime时可以互相调用,程序必须遵守共同的的Calling Convention,这也是ABI的一部分。推荐两本参考资料:x86 Assembly GuideComputer Systems: A Programmer’s Perspective从汇编看,完成一个函数调用关键执行就是 call, pushd,原创 2016-11-09 00:12:28 · 2982 阅读 · 0 评论 -
Linux 同步机制:信号量
临界区与共享资源信号量是一种同步机制,用来解决并发程序对共享资源访问的问题。同步:避免并发和防止竞争条件,任务有序协作执行。临界区:访问和操作共享数据的代码段。多线程并发访问同一个资源是通常是不安全的,临界区内往往要求做到原子执行。共享资源:需要被保护被锁的数据或者资源。信号量本质Linux 中的信号量是一种睡眠锁,本质是一种锁机制。当一个任务试图获取一个不可用的信号量是,信号量会将其推进一个原创 2016-12-18 23:20:53 · 629 阅读 · 0 评论