信号量和共享内存
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信号量(semaphore)Kless0329 (实现同步)
一种是系统调用,一种是调用linux库函数
信号量实现同步:
A B两个程序打印AA B
B 使每一次都连着打印A或B 只需一对信号量val= 1 A(p(0),v(0)) B(p(0),v(0)) p(0):是对val值为0的信号量进行p操作
AB两个程序进行读写同步,A写一个,B读一个,需要两对信号量(val= 1和val = 0,A( p(1),v(0) ) B( p(0),v(1) ) )
一、系统调用(2)
1、创建信号量(semget),成功后设置信号量的值(semctl) == 另一个进程获取信号量
2、进行pv操作(semop)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
通过key获取semid
pv 操作就是对senbuf 里面的内容进行改动sem_num 只有一个,所以下标就是0
删除时是删除信号量集
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3、删除信号量(semctl)
注意:删除操作必须在pv操作结束后进行(与共享内存对比)
只需删除一次,不论在哪个进程中删除都可以
1、创建
2、操作
3、删除
二、调用库函数(3)
value :信号量的初始化值
和大多数linux函数一样,这些函数成功是返回0,失败时返回-1
三、命令删除
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
如果
Pv操作中
Struct sembuf buf;
Buf.sem_flg = SEM_UNDO; // SEM_NOW AIT 不赋值就会在程序结束后系统自动删掉
(如果将pv操作中的Buf.sem_flg = SEM_UNDO;
则必须在完成各种操作之后删除,因为如果不删除,程序结束后,系统不会自动
共享内存kless0402 (实现进程间的通信(IPC)有三个:管道,信号,共享内存)
系统调用(2)
1、每个进程都有自己的逻辑地址
2、共享内存:一个物理内存被多个进程来访问
目的:是用来进行进程之间通信,(信号,共享内存,管道)
创建:专门开辟一个某个大小的内存,用来作为共享内存
3、达到共享内存需要的函数
1、Shmget: 全新创建,或是获取
2、Shmat: 将共享内存映射到某个进程shm_addr = NULL 原因:该进程的某个位置,让他自动判断,因为和硬件关联度大
3、Shmdt: 断开,使内存不映射到该进程
4、Shmctl: “删除内存”cmd = IPC_RMID (可以在断开之前删除,与信号量对比)
5、只需删除一次
(可以在断开之前删除)
若程序结束后,未删除,系统不会自动删除
7、不断开,会自动断开,但不会删除,不论在那个映射的进程中删除都可以
8、linux服务器中,我用命令ipcs 去查看时,看到如下数据
key shmid owner perms bytes nattch status
ox00 3501612 root 600 10734227 384 dest
ox00 3501613 apache 666 10000 0
dest 表示共享内存段已经被删除,但是仍然有程序在连接着它
“status栏中列出当前共享内存的状态,当该段内存的mode字段设置了SHM_DEST位时就会显示"dest"字样,
当用户调用shmctl的IPC_RMID时,内核首先看有多少个进程还和这段内存关联着,如果关联数为0,就会销毁(释放)这段内存,否则就设置这段内存的mode位SHM_DEST,”
6、创建一个共享内存,从A程序中输入字符串,从B程序中输出字符串,并用信号量做同步(shm.c shm1.c (sem.c))
0 1 v 3 p //信号量初始化为0 在A中先写v操作
在B中先写p操作
1、创建(shmget())
2、映射(shmat())
3、删除(shmctl())(可将buf置为NULL)
4、命令删除
一般经验:
大多数linux中的库函数,失败:-1 成功:0
大多数linux中的系统调用,成功:与操作有关的标识符或其它或-1,失败:0
消息队列kless0405 提供一种从一个进程向一个进程发送一个数据块的方法,每个数据块都被认为含有一个类型。
(系统调用函数)
1、和管道相比:
未解决管道满时的阻塞问题
优势:它独立于发送和接收进程而存在,这消除了在同步命名管道的打开和关闭时产生的一些困难。
提供了一种在两个不相关的进程之间传递数据的相当有效的方法
1、所用到的函数(系统调用2)
取消,不会有影响)