并发程序设计(续)

十二、共享内存

一、内存映射的基本使用

(一)内存映射的概念

1、共享内存的概念

并发程序设计(续)_第1张图片

1)使用一个磁盘文件与内存中的一个缓冲区映射

2)可以像访问普通内存一样对文件访问

3)不需要read,write函数

2、优点

并发程序设计(续)_第2张图片

使用内存映射后:

并发程序设计(续)_第3张图片

1)访问硬碟磁盘是毫秒级别,访问内存是纳秒级别,可以提高访问效率,差距很大,提高速度

并发程序设计(续)_第4张图片

2)文件的映射可以是一部分

(二)内存映射使用

1、mmap函数

并发程序设计(续)_第5张图片

并发程序设计(续)_第6张图片

参数:

1)addr:要映射的内存,一般为空,os自动选择合适的(内存管理一般是os来做,程序员不干预)

2)length:从头开始,映射多大

3)prot:共享内存访问权限,可读,可写,可执行,不可访问

4)flags:属性

进程间通讯必选共享的

在访问动态链接库,动态内存空间时,一个进程频繁的操作内存空间,也可以用内存映射,防止多次写磁盘

匿名管道参数:血缘关系进程

         

5)fd:映射文件,匿名-1

6)offset:文件偏移,一般从头0开始

2、mmap函数返回值:成功返回映射区首地址

3、代码实现:

1、读操作

并发程序设计(续)_第7张图片

2、写操作

1)通过代码写入磁盘

并发程序设计(续)_第8张图片

2)直接在test文件中写

(三)内存映射注意事项

1、映射区权限<=文件的打开权限

只读打开:

读写映射:

报错:

解决:增加文件权限

2、总线错误

映射文件的大小必须大于0

touch了原始文件test后,需要在test用空格敲出大小,如果不写,映射文件的大小为0,总线错误会乱码

文件大小大于7,可以写入数据:

2、如果是私有操作,不会写入磁盘

二、内存映射使用注意事项

1、在创建映射区时,包含一次对映射区的写操作

2、对于私有权限

读操作可以:

写操作不行:不会保存到磁盘中

并发程序设计(续)_第9张图片

3、映射之前关闭文件,不能正确读写

映射成功后,关闭文件可以进行正常的读-写

4、映射的文件大小不能为0(空格),总线错误,指定0大小的创建映射区,非法参数

5、

6、映射位置必须从4的整数倍开始,因为内存分配是按页

非法参数:

7、申请内存超过4k会报错

并发程序设计(续)_第10张图片

并发程序设计(续)_第11张图片

1)申请2k,访问3k可以 

并发程序设计(续)_第12张图片

2)申请2k,访问5k报错(超过4k)

并发程序设计(续)_第13张图片

8、

三、内存映射实现进程间的通信

1、写函数

并发程序设计(续)_第14张图片

2、读函数

并发程序设计(续)_第15张图片

实验结果

并发程序设计(续)_第16张图片

4、匿名映射-血缘进程

并发程序设计(续)_第17张图片

5、释放内存

并发程序设计(续)_第18张图片

四、systemV共享内存

(一)SYSTEM V概念

(二)使用步骤

并发程序设计(续)_第19张图片

1、IPC是进程间通信的缩写

并发程序设计(续)_第20张图片

 十三、信号机制上

*一、信号的概念

(一)信号机制

并发程序设计(续)_第21张图片

1、信号相当于一种软中断,软件模拟

2、不同的信号类型代表不同的事件

3、信号的产生

并发程序设计(续)_第22张图片

4、忽略信号:闯红灯

5、捕捉信号:知道信号,走其他  路

6、缺省方式:系统默认的方式

(二)常用信号

并发程序设计(续)_第23张图片

1、SIFHUP:关闭终端,发送给相关进程,默认停止

并发程序设计(续)_第24张图片

关闭一终端,在另外一个终端看不到运行的程序

2、SIGINT:ctrl+c,内核发送到所有前台进程(不会影响守护进行)

3、SIGQUIT:与SIGINT类似,指令是,CTRL+\

4、SIGILL:进程执行非法指令

5、SIGSEV:非法访问内存,野指针,缓冲区溢出

并发程序设计(续)_第25张图片

6、SIGPIPE:进程写入一个没有读端的管道,“管道断裂”

并发程序设计(续)_第26张图片

7、SIGKILI:结束进程,kill -9命令,不能捕捉和忽略

8、SIGSTOP:暂停进程,不能被捕捉和忽略

9、SIGALRM:定时器已到

10、SIGCHLD:子进程状态改变,发给父进程

(三)信号相关命令

1、kill/killall

并发程序设计(续)_第27张图片

1)kill -l查看所有的信号

并发程序设计(续)_第28张图片

kill -9 pid:杀死进程

2)kill -2 

并发程序设计(续)_第29张图片

3)kill -11:段错误退出

并发程序设计(续)_第30张图片

4)Killall+进程名

并发程序设计(续)_第31张图片

(四)信号发送

并发程序设计(续)_第32张图片

并发程序设计(续)_第33张图片

1、kill函数

并发程序设计(续)_第34张图片

并发程序设计(续)_第35张图片

2、raise函数

并发程序设计(续)_第36张图片

3、定时器函数

SIGALRM

并发程序设计(续)_第37张图片

并发程序设计(续)_第38张图片

(五)定时器

1、alarm函数

2、pause函数

并发程序设计(续)_第39张图片

3、一次性定时

并发程序设计(续)_第40张图片

4、循环定时

并发程序设计(续)_第41张图片

并发程序设计(续)_第42张图片

(六)信号捕捉

并发程序设计(续)_第43张图片

1、signal函数-捕捉信号执行自定义函数

并发程序设计(续)_第44张图片

1、函数

并发程序设计(续)_第45张图片

2、结果

ctrl+c没有结束,而是打印定义的函数

并发程序设计(续)_第46张图片

3、在自定义中恢复函数功能

并发程序设计(续)_第47张图片

(七)信号集和信号屏蔽

二、信号的发送和定时器

三、信号的捕捉

1、signal()函数版本问题不建议,推荐sigaction函数

并发程序设计(续)_第48张图片

并发程序设计(续)_第49张图片

1、函数

并发程序设计(续)_第50张图片

2、结果

并发程序设计(续)_第51张图片

3、alarm定时器操作,每过1秒,捕捉一次定时器信号

并发程序设计(续)_第52张图片

并发程序设计(续)_第53张图片

4、setitimer-alarm

四、信号SIGCHLD的使用

并发程序设计(续)_第54张图片

子进程状态改变时发送的

配合wait函数,wait函数不使用信号会阻塞父进程

并发程序设计(续)_第55张图片

并发程序设计(续)_第56张图片

并发程序设计(续)_第57张图片

 十三、信号机制下

一、信号的阻塞和信号集

1、信号是软中断,打断程序

2、忽略信号也被打断了,只是不执行信号

3、信号阻塞可以实现程序不被打断

,过段时间可以恢复信号

4、信号的递达:信号执行的处理过程:忽略,执行默认,捕获

5、信号的未决:从产生到递达之间的状态,相当于挂起

6、信号集

并发程序设计(续)_第58张图片

通过信号屏蔽字决定信号阻塞还是执行,1屏蔽

7、信号集的定义

并发程序设计(续)_第59张图片

1)定义:64bit/128bit,每个bit表示一个信号

2)被添加到信号集中的信号被置1阻塞

8、信号屏蔽函数

并发程序设计(续)_第60张图片

并发程序设计(续)_第61张图片

1)首先用sigaction函数捕捉SIGINT(注意sigaction函数的结构体)

2)定义一个信号集-制空-添加信号

并发程序设计(续)_第62张图片

3)unblock参数,5秒中恢复

二、信号驱动任务-pause函数

并发程序设计(续)_第63张图片

1、程序

并发程序设计(续)_第64张图片

2、结果-每一次ctrl+c,mytask就执行一次

并发程序设计(续)_第65张图片

3、设置多个信号捕捉

并发程序设计(续)_第66张图片

并发程序设计(续)_第67张图片

4、加锁-不会中断程序

并发程序设计(续)_第68张图片

并发程序设计(续)_第69张图片

并发程序设计(续)_第70张图片

在mytest执行中的信号是无效信号,不会被捕捉,已经被处理

5、

并发程序设计(续)_第71张图片

并发程序设计(续)_第72张图片

十四、消息队列

一、消息队列机制

1、进程间通讯的手段,不是先进先出。古老。

并发程序设计(续)_第73张图片

并发程序设计(续)_第74张图片

2、内核中的数据结构

并发程序设计(续)_第75张图片

并发程序设计(续)_第76张图片

3、消息队列的使用步骤

并发程序设计(续)_第77张图片

并发程序设计(续)_第78张图片

并发程序设计(续)_第79张图片

并发程序设计(续)_第80张图片

1、打开队列函数msgget

并发程序设计(续)_第81张图片

并发程序设计(续)_第82张图片

 

你可能感兴趣的:(linux,运维,服务器)