社区
Linux/Unix社区
帖子详情
linux下共享内存 函数shmat()的使用!
moye115
2011-05-03 08:13:45
在使用共享内存的时候,申请了一块连续的内存段,启动两个线程,一个不断地向其中写,一个不断地读取数据。
通过共享内存的shmat()函数怎么实现?
哪个高手指点指点!
...全文
330
6
打赏
收藏
linux下共享内存 函数shmat()的使用!
在使用共享内存的时候,申请了一块连续的内存段,启动两个线程,一个不断地向其中写,一个不断地读取数据。 通过共享内存的shmat()函数怎么实现? 哪个高手指点指点!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
6 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
su47flying
2011-05-05
打赏
举报
回复
一般共享内存和信号量(semphore)是一起使用的。
玩世不恭
2011-05-04
打赏
举报
回复
如果是线程,本来就共享所有的数据和代码空间,当然不包括堆栈空间,所以不需要使用shmat()了
当然,如果你说错了,应该是进程的话,就需要用shmat
Wind_Runner
2011-05-04
打赏
举报
回复
通过获取共享内存的地址可使得两个线程可以找到该内存,
要做的一是读写指针的处理,二是互斥读写的处理
justkk
2011-05-04
打赏
举报
回复
需要采用某种同步措施,以同步两个线程的读写操作,如互斥锁、信号灯、管道..
连接共享内存之后,两个线程在获取互斥锁后做相应的操作就行了,完成之后解锁
李亚超
2011-05-03
打赏
举报
回复
1:建立一个互斥锁,保证读写数据的一致性
2:读写
guoxuqu
2011-05-03
打赏
举报
回复
linux程序设计上有例子,请看第14章第二节共享内存
linux
共享内存
浅析
要
使用
共享内存
,应该有如下步骤: 1.开辟一块
共享内存
sh
mget() 2.允许本进程
使用
共某块
共享内存
sh
mat
() 3.写入/读出 4.禁止本进程
使用
这块
共享内存
sh
mdt() 5.删除这块
共享内存
sh
mctl()或者命令行下ipcrm ftok()。它有两个参数,一个是字符串,一个是字符。字符串一般用当前进程的程序名,字符一般用来标记这个标识符所标识的
共享内存
是这个进程所开辟的第几个
共享内存
。ftok()会返回一个key_t型的值,也就是计算出来的标识符的值。
sh
mkey = ftok( "mcut" , 'a' ); // 计算标识符 操作
共享内存
,我们用到了下面的
函数
#include #include #include int
sh
mget( key_t
sh
mkey , int
sh
msiz , int flag ); void *
sh
mat
( int
sh
mid , char *
sh
maddr , int
sh
mflag ); int
sh
mdt( char *
sh
maddr );
sh
mget()是用来开辟/指向一块
共享内存
的
函数
。参数定义如下: key_t
sh
mkey 是这块
共享内存
的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。但是刚才我们的两个进程没有任何关系,所以就用ftok()算出来一个标识符
使用
了。 int
sh
msiz 是这块内存的大小. int flag 是这块内存的模式(mode)以及权限标识。 模式可取如下值: 新建:IPC_CREAT
使用
已开辟的内存:IPC_ALLOC 如果标识符以存在,则返回错误值:IPC_EXCL 然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。 如: IPC_CREAT | IPC_EXCL | 0666 这个
函数
成功时返回
共享内存
的ID,失败时返回-1。 //
sh
mid开辟
共享内存
sh
mid =
sh
mget(
sh
mkey , sizeof(in_data) , IPC_CREAT | 0666 ) ;
sh
mat
()是用来允许本进程访问一块
共享内存
的
函数
。 int
sh
mid是那块
共享内存
的ID。 char *
sh
maddr是
共享内存
的起始地址 int
sh
mflag是本进程对该内存的操作模式。如果是
SH
M_RDONLY的话,就是只读模式。其它的是读写模式 成功时,这个
函数
返回
共享内存
的起始地址。失败时返回-1。 char *head , *pos , head = pos =
sh
mat
(
sh
mid , 0 , 0 ); // 允许本进程
使用
这块
共享内存
sh
mdt()与
sh
mat
()相反,是用来禁止本进程访问一块
共享内存
的
函数
。 参数char *
sh
maddr是那块
共享内存
的起始地址。 成功时返回0。失败时返回-1。
sh
mdt( head ); // 禁止本进程
使用
这块内存 此外,还有一个用来控制
共享内存
的
sh
mctl()
函数
如下: #include #include #include int
sh
mctl( int
sh
mid , int cmd , struct
sh
mid_ds *buf ); int
sh
mid是
共享内存
的ID。 int cmd是控制命令,可取值如下: IPC_STAT 得到
共享内存
的状态 IPC_SET 改变
共享内存
的状态 IPC_RMID 删除
共享内存
struct
sh
mid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变
共享内存
的状态,用这个结构体指定。 返回值: 成功:0 失败:-1
sh
mctl(
sh
mid,IPC_RMID,NULL); 刚才我们的mpaste.c程序中还可以加入这样几句。 struct
sh
mid_ds buf; ... ...
sh
mctl(
sh
mid , IPC_STAT , &buf ); // 取得
共享内存
的状态 ... ...
sh
mctl(
sh
mid , IPC_RMID , &buf ); // 删除
共享内存
注意:在
使用
共享内存
,结束程序退出后。如果你没在程序中用
sh
mctl()删除
共享内存
的话,一定要在命令行下用ipcrm命令删除这块
共享内存
。你要是不管的话,它就一直在那儿放着了。 简单解释一下ipcs命令和ipcrm命令。 取得ipc信息: ipcs [-m|-q|-s] -m 输出有关
共享内存
(
sh
ared memory)的信息 -q 输出有关信息队列(me
Linux
/Unix
共享内存
共享内存
是系统出于多个进程之间通讯的考虑,而预留的的一块内存区。在/proc/sys/kernel/目录下,记录着
共享内存
的一些限制,如一个
共享内存
区的最大字节数
sh
mmax,系统范围内最大
共享内存
区标识符数
sh
mmni等,可以手工对其调整,但不推荐这样做。 一、应用
共享内存
的
使用
,主要有以下几个API:ftok()、
sh
mget()、
sh
mat
()、
sh
mdt()及
sh
mctl()。 1)用ftok()
函数
获得一个ID号. 应用说明: 在IPC中,我们经常用用key_t的值来创建或者打开信号量,
共享内存
和消息队列。
函数
原型: key_t ftok(const char *pathname, int proj_id); Keys: 1)pathname一定要在系统中存在并且进程能够访问的 3)proj_id是一个1-255之间的一个整数值,典型的值是一个ASCII值。 当成功执行的时候,一个key_t值将会被返回,否则-1被返回。我们可以
使用
strerror(errno)来确定具体的错误信息。 考虑到应用系统可能在不同的主机上应用,可以直接定义一个key,而不用ftok获得: #define IPCKEY 0x344378 2)
sh
mget()用来开辟/指向一块
共享内存
的
函数
应用说明:
sh
mget()用来获得
共享内存
区域的ID,如果不存在指定的共享区域就创建相应的区域。
函数
原型: int
sh
mget(key_t key, size_t size, int
sh
mflg); key_t key 是这块
共享内存
的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。如果两个进程没有任何关系,所以就用ftok()算出来一个标识符(或者自己定义一个)
使用
了。 int size 是这块内存的大小. int flag 是这块内存的模式(mode)以及权限标识。 模式可取如下值: IPC_CREAT 新建(如果已创建则返回目前
共享内存
的id) IPC_EXCL 与IPC_CREAT结合
使用
,如果已创建则则返回错误 然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。 如: IPC_CREAT | IPC_EXCL | 0640 例子中的0666为权限标识,4/2/1 分别表示读/写/执行3种权限,第一个0是UID,第一个6(4+2)表示拥有者的权限,第二个4表示同组权限,第3个0表示他人的权限。 这个
函数
成功时返回
共享内存
的ID,失败时返回-1。 关于这个
函数
,要多说两句。 创建
共享内存
时,
sh
mflg参数至少需要 IPC_CREAT | 权限标识,如果只有IPC_CREAT 则申请的地址都是k=0xffffffff,不能
使用
; 获取已创建的
共享内存
时,
sh
mflg不要用IPC_CREAT(只能用创建
共享内存
时的权限标识,如0640),否则在某些情况下,比如用ipcrm删除
共享内存
后,用该
函数
并用IPC_CREAT参数获取一次
共享内存
(当然,获取失败),则即使再次创建
共享内存
也不能成功,此时必须更改key来重建
共享内存
。 3)
sh
mat
()将这个内存区映射到本进程的虚拟地址空间。
函数
原型: void *
sh
mat
( int
sh
mid , char *
sh
maddr , int
sh
mflag );
sh
mat
()是用来允许本进程访问一块
共享内存
的
函数
。 int
sh
mid是那块
共享内存
的ID。 char *
sh
maddr是
共享内存
的起始地址,如果
sh
maddr为0,内核会把
共享内存
映像到调用进程的地址空间中选定位置;如果
sh
maddr不为0,内核会把
共享内存
映像到
sh
maddr指定的位置。所以一般把
sh
maddr设为0。 int
sh
mflag是本进程对该内存的操作模式。如果是
SH
M_RDONLY的话,就是只读模式。其它的是读写模式 成功时,这个
函数
返回
共享内存
的起始地址。失败时返回-1。 4)
sh
mdt()
函数
删除本进程对这块内存的
使用
,
sh
mdt()与
sh
mat
()相反,是用来禁止本进程访问一块
共享内存
的
函数
。
函数
原型: int
sh
mdt( char *
sh
maddr ); 参数char *
sh
maddr是那块
共享内存
的起始地址。 成功时返回0。失败时返回-1。 5)
sh
mctl() 控制对这块
共享内存
的
使用
函数
原型: int
sh
mctl( int
sh
mid , int cmd , struct
sh
mid_ds *buf ); int
sh
mid是
共享内存
的ID。 int cmd是控制命令,可取值如下: IPC_STAT 得到
共享内存
的状态 IPC_SET 改变
共享内存
的状态 IPC_RMID 删除
共享内存
struct
sh
mid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变
共享内存
的状态,用这个结构体指定。 返回值: 成功:0 失败:-1
linux
kernel 源码剖析
共享内存
部分
这是我剖的2.6.15版本的
linux
内核源码
共享内存
部分源码 其中包括
sh
mget
sh
m
mat
sh
mdt
sh
mctl
函数
的内核调用,以及内核创建
共享内存
的过程。
Linux
进程间通信
sh
mget
函数
sh
mat
函数
Linux
进程间通信——
使用
共享内存
使用
消息队列进行进程间通信
linux
sh
mat
函数
,
Linux
共享内存
一、
共享内存
的概念
共享内存
(
Sh
ared Memory)就是允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间
共享内存
安排为同一段物理内存,进程可以将
共享内存
连接到它们自己的地址空间中,如果某个进程修改了
共享内存
中的数据,其它的进程读到的数据也将会改变。
共享内存
并未提供锁机制,也就是说,在某一个进程对
共享内存
的进行读写的时候,不会阻止其它的进程对它的...
Linux/Unix社区
23,120
社区成员
74,507
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章