Skip to content

Commit 9115229

Browse files
committed
update
1 parent 842876f commit 9115229

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

linux/.3.进程间通信.md.swp

-20 KB
Binary file not shown.

linux/3.进程间通信.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,5 +216,138 @@ ipcrm 删除IPC对象
216216
- 消息队列可以实现消息的随机查询,消息队列不一定以先进先出的次序读取,编程时可以按消息的类型读取。
217217
- 消息队列允许一个或多个进程向它写入或者读取消息。
218218
- 每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。
219+
- IPC通信机制需要一个key值,通过key值可以在系统内获得一个唯一的消息队列标识符。key值可以是人为指定的,也可以通过ftok()函数获得
220+
- 如果多个进程想通过IPC对象通信,则必须找到唯一的标识,而唯一的标识是由key决定的,所以只要key知道,则就可以实现多个进程通信
221+
222+
#### ftok()函数
223+
224+
```c
225+
#include <sys/types.h>
226+
#include <sys/ipc.h>
227+
228+
key_t ftok(const char *pathname, int proj_id);
229+
```
230+
功能: 获取项目相关的唯一的IPC键值。
231+
pathname: 路径名
232+
proj_id: 项目ID,非0整数(只有低8位有效)
233+
成功则返回key值,失败返回-1。
234+
235+
236+
如果使用ftok()函数获取键值,得到的键值是由ftok的第一个参数对应文件的信息和第二个参数一起决定的。
237+
只要保证ftok()函数的第一个参数对应的文件和第二个参数值相同,则不管程序运行多少遍,得到的key值都是一样的。
238+
239+
240+
#### 创建消息队列
241+
242+
```c
243+
#include <sys/msg.h>
244+
int msgget(key_t key, int msgflg);
245+
```
246+
247+
创建一个新的活打开一个已经存在的消息队列,不同的进程调用此函数,只要用相同的key值就能得到同一个消息队列的标识符。
248+
249+
key: IPC键值
250+
msgflg: 标识函数的行为及消息队列的权限。可以为IPC_CREATE表示创建消息队列,或者为IPC_EXCL检测消息队列是否存在。
251+
252+
253+
#### 发送消息
254+
255+
```c
256+
#include <sys/msg.h>
257+
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
258+
```
259+
260+
将消息添加到消息队列。
261+
262+
- msqid: 消息队列的标识符
263+
- msgp: 待发送消息结构体的地址
264+
- msggsz: 消息正文的字节数
265+
- msgflg: 函数的控制属性
266+
267+
268+
269+
### 共享内存
270+
271+
共享内存允许两个或者多个进程共享给定的存储区域。
272+
273+
共享内存的特点:
274+
- 共享内存是进程间共享数据的一种最快的方法。
275+
一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
276+
277+
- 使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥
278+
若一个进程正在向共享内存去写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。
279+
280+
281+
![image](https://github.com/CharonChui/Pictures/blob/master/shared_memory.png?raw=true)
282+
283+
共享内存是进程间通信方式中效率最高的。
284+
原因在于进程是直接在物理内存上进行操作,将物理地址映射到用户进程这,所以只要对其地址进行操作,就是直接对物理地址操作。
285+
286+
287+
在ubuntu 12.04中共享内存限制值如下:
288+
- 共享存储区的最大字节数: 32M
289+
- 每个进程最多映射的共享存储区的个数: 4096
290+
291+
292+
293+
#### 获得一个共享存储标识符
294+
295+
```c
296+
#include <sys/ipc.h>
297+
#include <sys/shm.h>
298+
299+
int shmget(key_t key, size_t size, int shflg);
300+
```
301+
302+
功能: 创建或打开一块共享内存区
303+
304+
参数:
305+
- key: IPC键值
306+
- size: 该共享存储区的长度(字节)
307+
- shmflg: 标识函数的行为及共享内存的权限。
308+
309+
返回值:
310+
- 成功: 返回共享内存标识符。
311+
- 失败: 返回-1。
312+
313+
314+
#### 共享内存映射(attch)
315+
316+
```c
317+
#include <sys/types.h>
318+
#include <sys/shm.h>
319+
320+
void *shmat(int shmid, const void *shmaddr, int shmflg);
321+
```
322+
323+
作用: 将一个共享内存区映射到调用进程的数据段中。
324+
参数:
325+
326+
- shmid: 共享内存标识符。
327+
- shmaddr: 共享内存映射地址(若为NULL,则由系统自动指定),推荐使用NULL。
328+
- shmflg: 共享内存区的访问权限和映射条件。
329+
330+
返回值:
331+
- 成功: 返回共享内存区映射地址
332+
- 失败: 返回-1
333+
334+
335+
#### 解除共享内存映射(detach)
336+
337+
```c
338+
#include <sys/types.h>
339+
#include <sys/shm.h>
340+
341+
int shmdt(const void *shmaddr);
342+
```
343+
功能: 将共享内存和当前进程分离(仅仅是断开联系,并不是删除共享内存)
344+
345+
参数:
346+
- shmaddr: 共享内存映射地址。
347+
348+
349+
成功返回0,失败返回-1.
350+
351+
219352

220353

0 commit comments

Comments
 (0)