初学Linux--进程间通信(共享内存、信号量)

共享内存

基本概念
系统内核分配的一块存储区,该内存被映射到多个进程的各自的进程地址空间,多个进程都可以对共享内存中数据进行跟新。
1.编程模型:
首先用shmget创建一个共享内存,再调用shmat将共享内存映射至调用进程的地址空间。映射完成后通过返回的共享内存的读写指针进行读写,最后调用shmdt关闭共享内存的映射。
2.映射:
共享内存创建后,用户程序运行时,通过调用IPC接口函数将该存储区映射至应用程序的内存地址空间。成功映射后就可对共享内存的读写像读写进程一样快捷。
3.数据结构:
与其他IPC机制一样,共享内存也有键值与标识符。共享内存有访问计数器机制,每有一个进程进行一次共享内存的映射,计数器就会+1,解除-1,当访问计数器=0时,可真正解除。可以通过执行命令ipcs-m的输出项nattch查看共享内存的访问计数。共享内存创建后,系统内核为该共享内存分配了控制结构,该结构名为struct shmid_ds。位于<bits/shm.h>中。

共享内存编程
1.创建共享内存:

#include<sys/shm.h>
int shmget(key_t_key,size_t_size,int_shmflg);

2.映射共享内存:

#include<sys/shm.h>
void*shmat(int_shmid,_const void*_shmaddr,int_shmflg);

_shmid:共享内存标识符
_shmaddr:由调用shmat的用户进程指定的一个虚拟空间地址,新创建的共享内存将附着在该地址后
_shmflg:创建共享内存标志。

3.删除共享内存映射:

#include<sys/shm.h>
int shmdt(_cosnt void*_shmaddr);

4.控制共享内存:

#include<sys/shm.h>
int shmctl(int_shmid,int _cmd,struct shmid_ds*_buf);

_buf:指向shmid_ds结构的指针,在_cmd为IPC_STAT时,该参数用作输出,_cmd为IPC_SET时,用作输入。

信号量

PV操作原理
1.定义:
PV操作是两个操作的合称,这两个操作分别是P操作和V操作。P是指通过,V是指释放。他们都是一种操作系统“原语”是指不可中断的过程,即两者都是原子操作。PV操作的前提是假定存在整型变量sem,PV操作就是对其进行加减的过程。

P操作过程定义如下:
(1).sem减1;(2).若sem减一后仍然大于等于零,则P操作返回,该进程继续进行;(3).若sem减一后小于零,则该进程被阻塞,进入操作系统的阻塞队列。

V操作过程定义如下:
(1).sem加1;(2).若sem加一后大于零,则v操作返回,该进程继续进行;(3).若sem加一后小于等于零,则从操作系统的阻塞队列中唤醒一个阻塞在该信号量上的进程,然后再返回原进程继续执行。

2.PV操作的应用:
1.进程互斥:假设系统中存在一个文件,两个进程AB对其进行写,如果单独进行不会存在问题,但如果进程AB同时对文件进行写,那么会导致文件内容混乱。可以使用PV操作解决这个问题,首先定义一个信号量,其初始值为1.在进程A向文件写之前,先用P操作原语锁定资源,此时资源可用,P操作成功后。进程A打开向其中写入数据。写完后,关闭文件并调用V操作原语释放资源。进程B的操作过程相同。这样资源同一时刻只能被一个进程调用。
伪代码:

P(sem);
WriteFile;
V(sem);

2.进程同步:在多进程编程环境下,有时一个进程需要暂时阻塞,等待另一个进程进行相应处理。进程B结束后,进程A再继续进行。这种情况下,需要进程同步。PV操作解决这个问题:在系统中定义一信号量,初始值为0,进程A执行计算任务,执行完成后调用V操作通知进程B进行,进程B一开始就执行P操作,等待进程A结束。

信号量的基本概念
Linux的信号量机制在标准PV操作基础上进行了扩充,主要体现为:
- Linux支持信号组
- 每次信号量的PV操作不仅限于对信号量值加一或减一,而是加减任意数。
- 支持进程退出时回滚对信号量的修改。
信号量的控制结构:

struct semid_ds
{
struct ipc_perm sem_perm;
_time_t sem_otime;
unsigned long int_unused1;
_time_t sem_ctime;
unsigned long int_unused2;
unsigned long int sem_nsems;
unsigned long int_unused3;
unsigned long int_unused4;
}

位于头文件<bits/sem.h>

信号量编程
1.创建信号量:

#include<sys/sem.h>
int semget(key_t_key,int_nsems,in_semflg);

_key:键值
_nsems:信号量集中的信号量的个数
_semflg:创建信号量标志,主要包括两方面信息:1.访问权限信息,该信息将初始化信号量控制结构中的sem_perm权限结构,2.创建标志。

2.信号量操作:

#include<sys/sem.h>
int semop(int _semid,struct sembuf*_sops,size_t_nsops);

_semid:信号量集的标识符。
_sops:信号量集的操作缓存,实际是一个指向结构数组的指针,该结构定义如下:

struct sembuf{
unsigned short int sem_num;//信号量操作编号
short int sem_op;//信号量操作数
short int sem_ng;//信号量操作标志
};

3.信号量控制:

#include<sys/sem.h>
int semctl(int_semid,int_semnum,int_cmd,...);

参考《Linux编程从入门到精通》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值