嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY27
概述:
一、System V 共享内存
二、POSIX 信号量
三、POSIX 消息队列
笔记:
注意:
不论是怎样的通信,只要牵扯公共资源
读读不互斥
读写互斥
写写互斥
一、System V 共享内存
1.概念:
可以说,共享内存是一种最为高效的进程间通信方式。因为,进程可以直接读写内存,不需要任何数据的复制。为了在多个进程间交换信息。内核专门流出了一块内存。这段内存可以由需要访问的进程将其映射到自己的私有地址空间。因此,进程就可以直接读写这一内存区而不要进行数据的复制,从而大大提高了效率。当然,由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等。
2.实现过程:
共享内存的实现分为两个步骤:
(1)创建共享内存,这里用到的函数时shmget(),也就是从内存种获得一段共享内存区域。
(2)映射共享内存,也就是把这段创建的共享内存映射到具体的进程空间中,这里使用的函数时shmat()。到这里就可以使用这段共享内存了,也就是可以使用不带缓冲的I/O读写命令对其进行操作。
(3)撤销映射,使用shmdt()函数。
3.所用函数:
(1)ftok函数:
#include <sys/types.h>
#include <sys/ipc.h>
/\*
\*函数名:ftok
\*函数功能:convert a pathname and a project identifier to a
\* System V IPC key, Key可用于msgget, semget, or
\* shmget的key参数
\*函数参数:
\* const char \*pathname:想要输出的字符串的首地址
\* int proj\_id:一个整型标识
\*函数返回值:key\_t:成功返回一个key\_t的key,失败返回-1
\*/
key_t ftok(const char \*pathname, int proj_id);
(2)shmget函数:
#include <sys/ipc.h>
#include <sys/shm.h>
/\*
函数名:shmget
函数功能:获得共享内存
函数参数:key:共享内存的键值,多个进程可以通过它访问同一个共享内存。其中有个特殊值 IPC\_PRIVATE,用于创建当前进程的私有共享内存。
size:共享内存的大小
shmflg:同open()函数的权限位,也可以使用八进制表示法
函数返回值:
成功:共享内存段标识符
失败:-1
\*/
int shmget(key_t key, size_t size, int shmflg);
(3)shmat函数:
#include <sys/types.h>
#include <sys/shm.h>
函数参数:
shmid:要映射的共享内存区标识符。
shmaddr:将共享内存映射到指定地址若为NULL,则表示系统自动分配地址,并把该段共享 内存映射到调用进程的地址空间)
shmflg:SHM_RDONLY:共享内存只读
默认0:共享内存可读可写
函数返回值:成功:被映射的段地址
出错:-1
void \*shmat(int shmid, const void \*shmaddr, int shmflg);
(4)shmdt函数:
#include <sys/types.h>
#include <sys/shm.h>
函数原型:int shmdt(const void \*shmaddr);
函数参数:shmaddr:被映射的共享内存段地址
函数返回值:
成功:0
失败:-1
4.如何查看共享内存:
ipcs -m
5.如何删除共享内存:
ipcrm -m [shmid]
6.代码演示
1.read_p ---------------------------------------------------------------------------------------如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
typedef struct msgbuf {
long mtype; /\* message type, must be > 0 \*/
char mtext[50]; /\* message data \*/
}Msg_Buf;
int main()
{
//ftok
key_t key = -1;
key = ftok(".",'a');
if(key < 0)
{
puts("ftok err