文章目录前言原理初探共享内存的创建过程系列 API 的使用ftokshmgetshmatshmdtshmctl共享内存实例 前言 总结一下最近对于共享内存的学习, 可能比较浅显或者有疏漏, 欢迎指正! 原理初探 我们知道, 进程空间相互隔离, 互相对立, 但是共享内存允许多个进程可以访问同一块内存来达到进程间通信的目的. 共享内存是最高效的 IPC 机制, 它不涉及任何进程间的数据传输, 而且他和进程同处于用户空间, 不像消息队列, 信号量是内核空间的系统对象, 不需要花费额外的数据拷贝, 但是同时他并没有预防竞态条件, 也就是说在多进程利用共享内存进行通信的情况下, 我们需要自己去利用锁等操作来进行同步 共享内存的创建过程 当我们创建了一块共享内存, 其实是在 tmpfs 中创建了一个文件 (这个文件是存储于内存的), 也就意味着在 tmpfs 中创建了一个 iNode 节点 然后我们需要将这个创建好的文件映射到进程中 (如下图, 此图来自网络, 应该是哪个博客或者知乎吧…已经记不清了) 我们创 继续阅读 >>


吕子健 18/11/08 23:11:47
ArchLinux 安装及KDE桌面环境安装配置 首先,安装之前,需要一个“启动介质”,我这里习惯使用USB设备作为启动介质,这是由于ArchLinux滚动更新的特性,而且占用空间很小,以其他的方式安装个人认为不太适合。 话不多说,访问ArchLinux官方网站,点击右上角Download,在下方选择适合你的下载方式或镜像进行下载,我常用的地址是网易的镜像源,和清华大学的镜像源。下载完毕后,我一般使用开源工具Rufus将之写入到U盘中。 安装 将启动U盘插入到电脑中,选择从U盘启动,进入到archlinux的LiveCD模式,若使用网线连接,此时应已经自动配置好网络,可使用ping命令测试网络;若使用无线网络,则键入wifi-menu命令选择并登录无线网络。然后,输入以下命令保证系统时间是正确的: timedatectl set-ntp true 然后我们可以通过fdisk -l命令查看分区情况,若要在此时修改分区表,ArchLinux提供了命令parted和fdisk,可以在此时修改分区表。若要格式 继续阅读 >>


娄泽豪 18/09/22 22:22:39
三次握手过程中 TCP 的状态变化 三次握手的过程和本质 三种状态 socket 函数 listen 函数 connect 函数 accept 函数 值-结果参数 connect 函数在三次握手中的返回情况 总结一下近日所学的关于 TCP 建立连接 三次握手 的过程中, TCP 的 状态变化, 以及在这个过程中所用的 socket 函数, 对于各种情况会如何处理 涉及到 connect listen accept 函数 三次握手过程中 TCP 的状态变化 三次握手的过程和本质 如下图, 是一个 TCP 建立和断开连接的过程, 我们今天只讨论建立连接的三次握手过程 主动申请连接的一方(通常为客户端), 发送一个 SYN 报文段, 服务器在收到客户端发来的 SYN 报文段后, 回复一个 SYN 报文段, 并发送一个 ACK 以确认客户端的 SYN, 为了确认服务器的 SYN, 客户端也会回复一个 ACK 经 继续阅读 >>


吕子健 18/09/04 14:58:46
I/O多路复用的理解 先讲一个大家都比较熟悉的例子吧 小时候咱们都喜欢看《亮剑》、《雪豹》这一类的抗日剧,里面八路军在自己的驻地周围都会24小时分布一些暗哨,每当有鬼子要进行扫荡或者清剿的时候暗哨就会赶紧告诉驻地的八路军,有敌人过来了,赶紧抄家伙干仗了。其实这就和咱们要讲的I/O多路复用有异曲同工之处。 在我们接触I/O多路复用以前,在处理一些比较多的连接或者请求的时候大多数人会去使用类似下面这种方式去处理: while(1) { int cli_fd = accept(listen_fd, (struct sockaddr*)&addrCli, sizeof(addrCli)); ...../*开启一个线程或者开启一个进程*/ } 这么做看着十分的清爽,而且实现起来也相当的简单,但是服务器的主程序会一直阻塞在accept这个函数上,然后会一直去等待connect的到来,这种方法虽然十分的简单,但是在轮询的过程中耗费了大量的CPU时间,并且效率还十分的低下,因此我们要想 继续阅读 >>


李佳灏 18/08/14 16:27:10
信号是由用户、系统或者进程发送给目标进程的信息,用来通知目标进程的状态改变或系统异常。 发送信号 kill #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); 该函数可以把sig信号发送给pid指定的目标进程 pid 参数 含义 pid > 0 信号发送给PID为pid的进程 pid = 0 信号发送给本进程组内的其他进程 pid = -1 信号发送给除init进程外的所有进程,但发送者需要拥有对目标发送信号的权限 pid < -1 信号发送给组ID为-pid的进程组中的所有成员 特别的如果sig为0的时候,kill函数不发送任何信号。 kill函数成功时返回0,失败返回-1,并设置errno errno 含义 EINVAL 无效的信号 EPERM 继续阅读 >>


李佳灏 18/08/13 15:26:36
生产者——消费者模型顾名思义,就是一个或多个线程往仓库生产东西,另外的线程从仓库拿东西,在咱们的线程池中也有所应用。咱们看看维基的解释: 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。 说了这么多,大家还是有点晕乎乎的,咱们看代码吧 #include<stdio.h> #include<unistd.h> #include<string.h> #include<pthread.h> //1 : 1 #defi 继续阅读 >>


李佳灏 18/08/13 08:34:37
特点 Linux 内核于内核2.6.25提供了一种创建定时器的 API, 那就是 Linux 特有的 timerfd API, 并且该定时器可以从文件描述符中读取其创建的定时器到期通知. 这也意味着, 可以将文件描述符通过多路复用监听并读取, 而其他的定时器想要将一个 (或多个) 定时器与一组文件描述符放在一起同时监听可不是一件容易的事. 函数接口 timerfd 系列 API 有三个系统调用 : 第一个系统调用, 该系统调用创建一个新的定时器对象 : #include <sys/timerfd.h> int timerfd_create(int clockid, int flags); //成功返回一个指代该对象的文件描述符, 失败返回-1及errno 第一个参数 clockid 可以设置为 CLOCK_REALTIME 和 CLOCK_MONOTONIC CLOCK_REALTIME 可设定的系统级实时时钟. 相对时间,从1970. 继续阅读 >>


吕子健 18/08/10 22:26:11
介绍 时间轮顾名思义,就是将不同时间的定时任务放在一个轮子上,既然是轮子,肯定是会转动的,时间轮内指向槽的指针,以恒定的速度顺时针转动,每转动一步就指向下一个槽。,一次转动称为一次滴答(tick)。一个滴答的时间称为时间轮的槽间隔si,也就是心搏时间。一个时间轮若有N个槽,在它运转一周的时间是N * si。同一个槽上的定时器它们的定时时间相差N * si的整数倍。 对于时间轮来说,要提高精度,就要使si值足够小;要提高执行效率,则要求N值足够大。如图所示: 由图可知定时器在时间轮的槽上是以链表的形式存储的(双向链表),并且相同一条链(也就是同一个槽)上的定时器:它们的定时时间相差N*si的整数倍。时间轮就是利用这个关系将定时器散列到不同的链中。在插入槽中的时候采用的是头插的方法,这样可以减少不必要的遍历时间。但是正是因为一股脑的头插(无序),也造成了在我们每次转动的时候都不得不去遍历一遍链表。 对于时间轮来说,添加一个定时器的时间复杂度为O(1),删除一个定时器的时间复杂度也是O(1),执行一 继续阅读 >>


李佳灏 18/08/09 16:49:07
选择gettimeofday()函数的原因:精度比timer()函数高很多,time函数只精确到秒,而gettimeofday精确到微妙,足以满足各种所需,虽然有精度比它更高的,但是它的系统调用开销相对更小 函数原型 #include<sys/time.h> int gettimeofday(struct timeval* tv, struct timezone* tz); 成功返回0, 失败返回-1, 出错返回errno 参数意义 tv是指向下面这个结构体的一个指针 struct timeval { time_t tv_sec; suseconds_t tv_usec; } time_t 和suseconds_t 都是lont int 类型, tv_sec 表示Epoch 秒数, 而tv_usec 是额外的微妙精度 tz 是一个历史产物, 早期的UNIX实现用来获取系统的时区信息, 目前已经被废弃了, 应始终将其置为NULL. 继续阅读 >>


吕子健 18/08/03 17:16:10
在《Linux高性能服务器编程》一书中为了帮助大家将书中的知识融汇到实际项目中,作者特意编写了一个较为完整的负载均衡服务器程序springsnail。里面用到了进程池、有限状态机这些知识点。自己是在网上找到的这个程序的源码,起初接触的时候,总共1400多行代码里面没有一行注释,网上也没有一篇博客去对这个项目进行解析,因此写这篇博客供大家一起分享学习。springsnail源码(带注释) 咱们从main函数开始,我们要介绍几个c语言中的两个宏 __FILE__:用以指示本行语句所在源文件的文件名 __LINE__:用以指示本行语句在源文件中的位置信息 这两个参数在后面咱们程序的调试中有着非常正要的作用。并且整个程序的日志系统也是依靠这两个宏和可变参的log()函数完成的。 接着大家需要了解getopt函数这个函数可以通过提取命令行参数对命令行参数进行解析。 接着后面是解析xml文件的一长串代码 vector< host > balance_srv; 继续阅读 >>


李佳灏 18/08/02 12:33:17