特点:
共享内存的使用步骤:
key_t key = ftok(路径,int)
//key值打印出来:0x610191c8 01是系统编号//key("./app",'a')---a->0x61 app->1479112=0x191c8
int shmid = shmget(key, size, IPC_CREAT|IPC_EXCL|0666);
地址 = shmat(shmid, NULL, 0);
shmdt(地址);
shmctl(shmid, IPC_RMID, NULL);
ipcs
key_t ftok(const char *pathname, int proj_id);
功能:产生一个独一无二的key值
参数:
Pathname
:已经存在的可访问文件的名字
Proj_id
:一个字符(因为只用低8位)
返回值:成功:key
值
失败:-1
int shmget(key_t key, size_t size, int shmflg);
功能:创建或打开共享内存
参数:
key
键值
size
共享内存的大小
shmflg IPC_CREAT|IPC_EXCL|0777
返回值:成功 shmid
出错 -1
void *shmat(int shmid,const void *shmaddr,int shmflg);
功能:映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
参数:
shmid
共享内存的id号
shmaddr
一般为NULL
,表示由系统自动完成映射
如果不为NULL
,那么有用户指定
shmflg
:SHM_RDONLY
就是对该共享内存只进行读操作shm_rdonly
0 可读可写
返回值:成功:完成映射后的地址,
出错:-1地址
用法:if((p = (char *)shmat(shmid,NULL,0)) == (char *)-1)
int shmdt(const void *shmaddr);
功能:取消映射
参数:要取消的地址
返回值:成功0
失败的-1
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
功能:(删除共享内存),对共享内存进行各种操作
参数:
shmid
共享内存的id号
cmd
:IPC_STAT
获得shmid属性信息,存放在第三参数
IPC_SET
设置shmid属性信息,要设置的属性放在第三参数
IPC_RMID
:删除共享内存,此时第三个参数为NULL
即可
返回: 成功0
失败-1
用法:shmctl(shmid,IPC_RMID,NULL);
查看共享内存的命令:`ipcs -m`
删除共享内存的命令:`ipcrm -m [shmid] `
特点:
信号灯(semaphore
),也叫信号量。它是不同进程间
或一个给定进程内部不同线程间同步的机制
System V
的信号灯是一个或者多个信号灯的一个集合。
其中的每一个都是单独的计数信号灯。而Posix信号
灯指的是单个计数信号灯
信号灯种类:
posix
有名信号灯
posix
基于内存的信号灯(无名信号灯)
System V
信号灯(IPC对象)
创建步骤:
0. 创建key
值
ftok
1. 创建或打开信号灯集
semid = semget(key, num, flag);
2. 初始化信号灯
semctl(semid, 编号, SETVAL, union semun);
3. PV操作
semop(semid, struct sembuf, 1);
4. 删除信号灯集
semctl(semid, 0, IPC_RMID);
相关函数:
int semget(key_t key, int nsems, int semflg);
功能:创建/打开信号灯
参数:key
:ftok
产生的key
值
nsems
:信号灯集中包含的信号灯数目
semflg
:信号灯集的访问权限,通常为IPC_CREAT|IPC_EXCL|0666
返回值:成功:信号灯集ID
失败:-1
int semop ( int semid, struct sembuf *opsptr, size_t nops);
功能:对信号灯集合中的信号量进行PV操作
参数:semid
:信号灯集ID
struct sembuf {
short sem_num; // 要操作的信号灯的编号
short sem_op;
// 0 : 等待,直到信号灯的值变成0
// 1 : 释放资源,V操作
// -1 : 申请资源,P操作
short sem_flg;
// 0(阻塞),IPC_NOWAIT, SEM_UNDO
};
nops
: 要操作的信号灯的个数 1个
返回值:成功 :0
失败:-1
用法:
mysembuf.sem_num = 0;
mysembuf.sem_op = -1;
mysembuf.sem_flg = 0;
semop(semid, &mysembuf, 1);
mysembuf.sem_num = 0;
mysembuf.sem_op = 1;
mysembuf.sem_flg = 0;
semop(semid, &mysembuf, 1);
int semctl ( int semid, int semnum, int cmd…/*union semun arg*/);
功能:信号灯集合的控制(初始化/删除)
参数:semid
:信号灯集ID
semnum
: 要操作的集合中的信号灯编号
cmd
:
GETVAL
:获取信号灯的值,返回值是获得值
SETVAL
:设置信号灯的值(资源量),
需要用到第四个参数:共用体
IPC_RMID
:从系统中删除信号灯集合
返回值:成功 0
失败 -1
用法:
union semun{
int val;
}mysemun;
mysemun.val = 10;
semctl(semid, 0, SETVAL, mysemun);
semctl(semid, 0, GETVAL)
的返回值semctl(semid, 0, IPC_RMID);
查看信号灯集的命令:ipcs -s
删除信号灯集的命令:ipcrm -s [semid]
key
值ftok
int msgget(key_t key, int flag);
功能:创建或打开一个消息队列
参数:key
值
flag
:创建消息队列的权限IPC_CREAT|IPC_EXCL|0666
返回值:成功:msgid
失败:-1
int msgsnd(int msqid, const void *msgp, size_t size, int flag);
功能:添加消息
参数:msqid
:消息队列的ID
msgp
:指向消息的指针。常用消息结构msgbuf如下:
struct msgbuf{
long mtype; //消息类型
char mtext[N];
}; //消息正文
size
:发送的消息正文的字节数
flag
:IPC_NOWAIT
消息没有发送完成函数也会立即返回
0
:直到发送完成函数才返回
返回值:成功:0
失败:-1
使用:msgsnd(msgid, &msg,sizeof(msg)-sizeof(long), 0)
注意:消息结构除了第一个成员必须为long类型外,其他成员可以根据应用的需求自行定义。
int msgrcv(int msgid, void* msgp, size_t size, long msgtype, int flag);
功能:读取消息
参数:msgid:消息队列的ID
msgp
:存放读取消息的空间
size
:接受的消息正文的字节数
msgtype
:
0:接收消息队列中第一个消息。
大于0:接收消息队列中第一个类型为msgtyp的消息.
小于0:接收消息队列中类型值不小于msgtyp的绝对值且类型值又最小的消息。
flag
:0
:若无消息函数会一直阻塞
IPC_NOWAIT
:若没有消 息,进程会立即返回E NO MSG
返回值:成功:接收到的消息的长度
失败:-1
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
功能:对消息队列的操作,删除消息队列
参数:msqid
:消息队列的队列ID
cmd
:
IPC_STAT
:读取消息队列的属性,并将其保存在
buf指向的缓冲区中。
IPC_SET
:设置消息队列的属性。这个值取自buf参数。
IPC_RMID
:从系统中删除消息队列。
buf:消息队列缓冲区
返回值:成功:0
失败:-1
用法:msgctl(msgid, IPC_RMID, NULL)
PCB:进程控制块