设为首页
加入收藏
首页
C语言
C++
面试
Linux
函数
Windows
数据库
下载
搜索
我要投稿
全站搜索
文章
图片
软件
视频
商品
FLASH
产品
高级搜索
当前位置:
首页
->
技术
TOP
进程间共享数据技术
2011-03-15 18:10:32
来源:
服务器开发
作者: 【
大
中
小
】 浏览:
542
次
Tags:
进程
共享
数据
技术
进程间共享数据技术是每个操作系统都具有的特性,而每个操作系统都会略有不同,而思路方面都是一致的。经过整理,各操作系统进程间共享数据技术存在以下四种方法
1:管道数据
2:Socket数据
3:共享内存
4:文件方式
之前广州某项目曾经考虑过使用管道实现,当然后来考虑到压力并不是很大,就改用文件方式处理了。Socket数据就比较直接了,同正常的网络socket一致。共享内存技术是本文的一个重点介绍的内容。文件方式不外乎直接性质的文件写读操作,或者通过
数据库
的方式进行读写。
本文就Linux下面共享内存技术进行探讨,因为共享内存是进程间共享数据最快的方式。
Linux共享内存有两种模式(见参考文献 1,2):
mmap方法和shm方式。
这里具体说一下shm方式:
要使用共享内存,应该有如下步骤(见参考文献3):
引用
1.开辟一块共享内存 shmget()
2.允许本进程使用共某块共享内存 shmat()
3.写入/读出
4.禁止本进程使用这块共享内存 shmdt()
5.删除这块共享内存 shmctl()或者命令行下ipcrm
参考文献三中提到在使用shm方式的一些注意事项:
1:在使用 函数shmget的时候有一个key_t参数,我们可以使用
view plain
print
hmkey = ftok(
"mcut"
,
'a'
);
// 计算标识符
生成shmkey参数。
使用shm方式共享内存需要用到如下头文件:
view plain
print
#include
#include
#include
相关函数:
view plain
print
int
shmget( key_t shmkey ,
int
shmsiz ,
int
flag );
void
*shmat(
int
shmid ,
char
*shmaddr ,
int
shmflag );
int
shmdt(
char
*shmaddr );
参考文献四《共享内存的系统调用》提到:
例1. 创建关键字为0x1234,访问权限为0666,占用空间10K的共享内存,如果已存在则返回其标识号。
view plain
print
int
shmid;
shmid = shmget(0x1234, 10*1024, 0666|IPC_CREAT);
例2. 创建关键字为0x1234,访问权限为0666,占用空间10K的共享内存,如果已存在则报错。
view plain
print
int
shmid;
shmid = shmget(0x1234, 10*1024, 0666|IPC_CREAT|IPC_EXCL);
例3. 将创建关键字为0x1234,占用空间10K的共享内存,链接到进程中。
view plain
print
int
shmid;
char
*pmat;
shmid = shmget(0x1234, 10*1024, 0666|IPC_CREAT);
pmat = shmat(shmid, 0, 0);
例4. 释放进程中地址paddr处的共享内存映射。
view plain
print
char
*paddr;
int
ret;
ret = shmdt(paddr);
经过整理:可以写出如下类代码:
view plain
print
class
TShareMemory{
public
:
TShareMemory(
char
*name,
int
size);
~TShareMemory();
int
Write(
char
*buffer);
char
*Read(
int
size);
int
GetID(
void
){
return
segid;
}
private
:
char
*name;
int
size;
int
segid;
};
当然要完善,还要加上锁机制之类的。
在经典数据Unix网络
编程
(www.cppentry.com)卷二中有如下例子非常详细明显的使用信号量来互斥进程间数据的程序,本文根据连接 http://blog.chinaunix.net/u/22935/showart_298945.html 摘录如下:
服务器
端程序:
view plain
print
/*server.c服务器程序*/
#include
#include
#include
#include
#include
#include
#include
#include
union
semun{
int
val;
struct
semid_ds *buf;
unsigned
short
int
*array;
};
main(
int
argc,
char
**argv)
{
int
i,shm_id,sem_id,oflag;
int
value;
char
*ptr;
struct
sembuf lock_it;
union
semun options;
oflag=0644|IPC_CREAT;
if
(argc!=2)
{
printf(“usage:server \n”);
exit(1);
}
if
((sem_id=semget(ftok(argv[1],0),100,oflag))<0)
/*创建信号量*/
perror(“shmget”);
options.val=1;
semctl(sem_id,0,SETVAL,options);
/*设置信号量值*/
if
((shm_id=shmget(ftok(argv[1],0),100,oflag))<0)
/*创建共享内存区*/
perror(“shmget”);
if
((ptr=shmat(shm_id,NULL,0))<0)
/*连接到共享内存区*/
perror(“shmat”);
while
(1)
{
if
((strcmp(ptr,”\0”))==0)
/*如果共享内存区没有数据,则等待*/
{
continue
;
}
else
{
if
((strcmp(ptr,”q\n”))==0)
/*如果数据为”q\n”突出循环*/
break
;
lock_it.sem_num=0;
lock_it.sem_op=-1;
lock_it.sem_flg=IPC_NOWAIT;
semop(sem_id,&lock_it,1);
/*信号量减一*/
printf(“server:%s”,ptr);
/*读出共享内存区内容*/
strcpy(ptr,”\0”);
/*把共享内存区清0*/
lock_it.sem_num=0;
lock_it.sem_op=1;
lock_it.sem_flg=IPC_NOWAIT;
semop(sem_id,&lock_it,1);
/*信号量加一*/
}
}
semctl(sem_id,IPC_RMID,0);
shmctl(shm_id,IPC_RMID,0);
exit(0);
}
客户端程序:
view plain
print
/*user.c用户程序*/
#include
#include
#include
#include
#include
#include
#include
#include
union
semun{
int
val;
struct
semid_ds *buf;
unsigned
short
int
*array;
};
main(
int
argc,
char
**argv)
{
int
i,shm_id,sem_id;
int
value;
char
*ptr;
struct
sembuf lock_it;
union
semun options;
if
(argc!=2)
{
printf(“usage:server \n”);
exit(1);
}
if
((sem_id=semget(ftok(argv[1],0),0,0))<0)
/*打开信号量*/
perror(“shmget”);
if
((shm_id=shmget(ftok(argv[1],0),0,0))<0)
/*打开共享内存区*/
perror(“shmget”);
if
((ptr=shmat(shm_id,NULL,0))<0)
/*连接共享内存区*/
perror(“shmat”);
while
(1)
{
lock_it.sem_num=0;
lock_it.sem_op=-1;
lock_it.sem_flg=IPC_NOWAIT;
semop(sem_id,&lock_it,1);
/*信号量减一*/
fgets(ptr,10,stdin);
/*从键盘读入数据到共享内存区*/
printf(“user:%s”,ptr);
if
((strcmp(ptr,”q\n”))==0)
exit(0);
lock_it.sem_num=0;
lock_it.sem_op=1;
lock_it.sem_flg=IPC_NOWAIT;
semop(sem_id,&lock_it,1);
/*信号量加一*/
}
exit(0);
}
程序开辟共享内存后,容易造成一些问题就是下次创建的时候会报错17,表示EEXIST.
可以使用以下方法进行删除:
ipcs -m
获取到该共享内存的ID,然后删除ipc
ipcrm -m 上面获取到的ID
参考文献:
1:
Linux环境进程间通信(五): 共享内存(上)
2:
Linux环境进程间通信(五): 共享内存(下)
3:
共享内存---shmget shmat shmdt
4:
14.2.1 共享内存的系统调用
【
大
中
小
】【
打印
】
【
繁体
】【
投稿
】【
收藏
】 【
推荐
】【
举报
】【
评论
】 【
关闭
】 【
返回顶部
】
分享到:
上一篇
:
CORBA 入门
下一篇
:
MySQL数据库的高可用架构方案
评论
帐 号:
密码:
(
新用户注册
)
验 证 码:
表 情:
内 容:
Copyright@https://www.cppentry.com all rights reserved
粤ICP备13067022号-3
Powered by
qibosoft V7.0
Code © 2003-11
qibosoft