linux下进程间通信的机制
今天突然想起了nginx解决惊群的方法,就是在多个进程间利用锁来保证同一时刻只能有一个worker进程在自己的epoll中加入监听的句柄,那么进程间是怎么共享变量的呢,下面就介绍一下共享内存
共享内存是 Linux 下提供的最基本的进程间通信方法,它通过 mmap 或者 shmgat 系统调用在内存中创建了一块连续的线性地址空间,而通过 munmap 或者 shmdt 系统调用可以释放这块内存。使用共享内存的好处是当多个进程使用同一块共享内存时,在任何一个进程修改了共享内存中的内容后,其他进程通过访问这段共享内存都能够得到修改后的内容。
虽然 mmap 可以以磁盘文件的方式映射共享内存,但在 Nginx 封装的共享内存操作方法中是没有使用到映射文件功能的。
Nginx 定义了 ngx_shm_t 结构体,用于描述一块共享内存:
typedef struct {
/* 执行共享内存的起始地址 */
u_char *addr;
/* 共享内存的长度 */
size_t size;
/* 这块共享内存的名称 */
ngx_str_t name;
/* 记录日志的 ngx_log_t 对象 */
ngx_log_t *log;
/* 表示共享内存是否已经分配过的标志位,为 1 时表示已经存在 */
ngx_uint_t exists; /* unsigned exists:1 */
}ngx_shm_t;
操作 ngx_shm_t 结构体的方法有以下两个:
- ngx_shm_alloc:用于分配新的共享内存;
- ngx_shm_free:用于释放已经存在的共享内存。
mmap 系统调用简述
void *mmap(void *start, size_t length, int prot, int flags,
int fd, off_t offset);
mmap 可以将磁盘文件映射到内存中,直接操作内存时 Linux 内核将负责同步内存和磁盘文件中的数据:
- fd 参数就指向需要同步的磁盘文件
- offset 则代表从文件的这个偏移量开始共享。
- 当 flags 参数中加入 MAP_ANON 或者 MAP_ANONYMOUS 参数时表示不使用文件映射方式,这时 fd 和 offset 参数就没有意义了,也不需要传递,此时的 mmap 方法和 ngx_shm_alloc 的功能几乎完全相同。
- length 参数就是将要在内存中开辟的线性地址空间大小。
- prot 参数则是操作这段共享内存的方式(如只读或可读可写)。
- start 参数说明希望的共享内存起始映射地址,通常设为 NULL,即由内存选择映射的起始地址。
MAP_ANON 是 MAP_ANONYMOUS 的同义词,已过时。表示不使用文件映射方式,并且共享内存被初始化为0,因此忽略 mmap 中的 fd 和 offset 参数,但是为了可移植性,当 MAP_ANONYMOUS(或 MAP_ANON)被指定时,fd 应该设置为 -1。
如下为使用 mmap 实现的 ngx_shm_alloc 方法:
ngx_int_t
ngx_shm_alloc(ngx_shm_t *shm)
{
/* 开辟一块 shm->size 大小且可读/写的共享内存,内存首地址存放在 shm->addr 中 */
shm->addr = (u_char *)mmap(NULL, shm->size,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_SHARED, -1, 0);
if (shm->addr == MAP_FAILED) {
ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
"mmap(MAP_ANON|MAP_SHARED, %uz) failed", shm->size);
return NGX_ERROR;
}
return NGX_OK;
}
当不在使用共享内存时,需要调用 munmap 或者 shmdt 来释放共享内存:
int munmap(void *start, size_t length);
- start:指向共享内存的首地址
- length:表示这段共享内存的长度
Nginx 的 ngx_shm_free 方法封装了该 munmap 方法:
void
ngx_shm_free(ngx_shm_t *shm)
{
if (munmap((void*) shm->addr, shm->size) == -1) {
ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
"munmap(%p, %uz) failed", shm->addr, shm->size);
}
}
Nginx 各进程间共享数据的主要方式就是使用共享内存(在使用共享内存时,Nginx 一般是由 master 进程创建,在 master 进程 fork 出 worker 子进程后,所有的进程开始使用这块内存中的数据)。
Nginx 的共享内存有三种实现:
- 不映射文件使用 mmap 分配共享内存(即上面的代码)
- 以 /dev/zero 文件使用 mmap 映射共享内存
- 用 shmget 调用来分配共享内存
linux下进程间通信的机制的更多相关文章
- Linux下进程间通信的六种机制详解
linux下进程间通信的几种主要手段: 1.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具 ...
- linux下六大IPC机制【转】
转自http://blog.sina.com.cn/s/blog_587c016a0100nfeq.html linux下进程间通信IPC的几种主要手段简介: 管道(Pipe)及有名管道(named ...
- 2017-2018-1 20155222 《信息安全系统设计基础》第10周 Linux下的IPC机制
2017-2018-1 20155222 <信息安全系统设计基础>第10周 Linux下的IPC机制 IPC机制 在linux下的多个进程间的通信机制叫做IPC(Inter-Process ...
- Linux下的IPC机制
Linux下的IPC机制 IPC(Inter-Process Communication)是多个进程之间相互沟通的一种方法.在linux下有多种进程间通信的方法. 共享内存 Linux内存共享有多种, ...
- linux下epoll实现机制
linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...
- 浅析Linux下进程间通信:共享内存
浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...
- Linux下进程间通信--消息队列
消息队列的定义遍地都是,不想移驾,请看下文: 一.定义: 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认 为是有一个类型,接收者进程接收的数据块可以有不同的类型值.我 ...
- 【操作系统之三】Linux下进程间通信-IPC(Inter-Process Communication)
管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:信号(Sign ...
- Linux 下的同步机制
2017-03-10 回想下最初的计算机设计,在单个CPU的情况下,同一时刻只能由一个线程(在LInux下为进程)占用CPU,且2.6之前的Linux内核并不支持内核抢占,当进程在系统地址运行时,能打 ...
随机推荐
- Shell中test比较
数字比较 比较 描述 -eq 检查是否相等 -ge 检查是否大于或等于 -gt 检查是否大于 -le 检查是否小于或者等于 -lt 检查是否小于 -ne 检查是否不等于 字符串比较 = 检查字符串1和 ...
- 【图像算法OpenCV】几何不变矩--Hu矩
原文地址 http://blog.csdn.NET/daijucug/article/details/7535370 [图像算法OpenCV]几何不变矩--Hu矩 一 原理 几何矩是由Hu(Visu ...
- 关于MYSQL使用过程中的一些错误总结
一,java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 导致这个问题有很多种情况,我暂时遇到的是:未在lib下导入jar包. 这个链接是各个 ...
- OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
之前啃了不少OpenCV的官方文档,发现如果了解了一些OpenCV整体的模块架构后,再重点学习自己感兴趣的部分的话,就会有一览众山小的感觉,于是,就决定写出这篇文章,作为启程OpenCV系列博文的第二 ...
- Django 框架学习 ---- 安装
这里引用了源码方式安装: 1.git clone https://github.com/django/django.git 2.cd django/ 3.python setup.py install ...
- 2019牛客暑期多校训练营(第七场)-B Irreducible Polynomial(多项式因式分解)
题目链接:https://ac.nowcoder.com/acm/contest/887/B 题意:给定整系数多项数,判断实数域上是否可约. 思路: AC代码: #include<cstdio& ...
- [转帖]关于Java中SQL语句的拼接规则
关于Java中SQL语句的拼接规则 自学demo 的时候遇到的问题 结果应该是 '"+e.getName()+"' 注意 一共有三组标点符号 (除去 方法函数后面的括号) 实现目标 ...
- ARST第二周打卡
Algorithm : 做一个 leetcode 的算法题 题目:一个无序数组里有99个不重复正整数,范围从1到100,唯独缺少一个整数.如何找出这个缺失的整数? int FindOneMissNum ...
- 虚拟机(Vmware)安装ubuntu18.04和配置调整(二)
二.配置修改 1.修改语言环境(settings->Region & Language) 选中中文简体(Chinese(simplified)),点击Apply 中文简体语言安装完成后, ...
- JS实现点击查看密码功能,再次点击隐藏密码!
<table border='1'> <tr> <td>aaaa</td> <td onclick="myFunction(this.i ...