- 青岛雅思—专家谈雅思考试发展趋势
- 河南2011上半年自考网上报名入口 点击进入
- 2011年广东省护士资格考试报名现场确认时间
- 2011上半年乐山五通桥区会计从业考试报名3月10日-4月1
- 哈尔滨香坊区2011护士资格考试报名现场确认时间
- 2011什邡第一次会计从业资格考试报名3月1日-4月15日
- 2011什邡第二次会计从业资格考试报名7月1日-9月16日
- 2011年中山市护士资格考试报名工作的通知
- 长安大学2011考研成绩查询入口 点击进入
- 西华大学2011考研成绩查询入口 点击进入
- 中国地质大学(武汉)2011考研成绩3月3日查询
- 中南民族大学2011考研成绩查询3月4日开始
- 沈阳建筑大学2011考研成绩查询入口 点击进入
- 沈阳工业大学2011考研成绩查询入口 点击进入
【武汉华嵌】Linux进程间通信之共享内存
来源:求学问校网 发表时间:2011-11-03 浏览 45 次
作者:武汉华嵌技术部
共享内存区是可用IPC形式中最快的。一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核(这里说的不涉及内核的含义是:进程不再通过执行任何进入内核的系统调用来彼此传递数据)。然而往该共享内存区存放信息或从中取走信息的进程间通常需要某种形式的同步,同步的方式有多种,比如:信号量、互斥锁等等。
以下两图分别描述了读写消息时,一个要进入内核,而一个不进入内核的情况:
对于System V共享内存区,内核维护如下的信息结构,它定义在<sys/shm.h>头文件中:
struct shmid_ds{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* segment size */
.
.
.
};
有了以上的知识,那么如何来对共享内存进行操作呢,以下就开始讲解如何来操作:
创建一个新的共享内存区,或者访问一个已存在的共享内存区。
#include <sys/shm.h>
int shmget(key_t key, size_t size, into flag);
size以字节为单位指定内存区的大小。当实际操作为创建一个新的共享内存区时,必须指定一个不为0的size值。如果实际操作为访问一个已存在的共享内存区,那么size应为0。
oflag为读写权限值的组合。它还可以与IPC_CREAT或IPC_CREAT|IPC_EXCL按位或。
当实际操作为创建一个共享内存区时,该内存区被初始化为size字节的0。
由shmget创建或打开一个共享内存区后,通过调用shmat把它附接到调用进程的地址空间。
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int flag);
shmid是由shmget返回的标识符。Shmat的返回值是所指定的共享内存区在调用进程内的起始地址。确定这个地址的规则如下:
如果shmaddr是一个空指针,那么系统替调用者选择地址。(这个是推荐的方法)
如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND:
如果没有指定SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址;
如果指定了SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址向下舍入一个SHMLBA常值。
当一个进程完成共享内存区的使用时,它可调用shmdt断接这个内存区。
#include <sys/shm.h>
int shmdt(const void *shmaddr);
当一个进程终止时,它当前附接着的所有共享内存区都自动断接掉。
注意:本函数调用并不删除所指定的共享内存区。
shmctl提供了对一个共享内存区的多种操作。
#icnldue <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buff);
该函数提供了三个命令:
IPC_RMID 从系统中删除由shmid标识的共享内存区并拆除它。
IPC_SET 给所描写的共享内存区设置其shmid_ds结构的某些成员。
IPC_STAT 向调用者返回所指定共享内存区当前的shmid_ds结构。
以下是共享内存结合信号量进行操作的部份代码:
发关进程的部份代码:
//创建一个共享内存区
if((shmid1 = shmget(shmkey1, MAX_SHEARE_MEM_SIZE, IPC_CREAT|0666)) < 0)
{
perror("shmget");
}
//把共享内存区附接到调用进程的地址空间
if((sharmem = shmat(shmid1, NULL, 0)) < 0)
{
perror("shmat");
}
while(1)
{
sem_p(semid1); //semid1进行p操作,保护共享区
memset(buff, 0, MAX_SHEARE_MEM_SIZE);
printf("Input ou want to say with you friend!\n");
fgets(buff, MAX_SHEARE_MEM_SIZE, stdin);
if(strncmp(buff, "quit", 4))
{
//往共享内存区放入数据
strncpy(sharmem, buff, MAX_SHEARE_MEM_SIZE);
sem_v(semid2); //semid2进行v操作,释放对共享区的保护
}
else
{
strncpy(sharmem, buff, MAX_SHEARE_MEM_SIZE);
sem_v(semid2);
break;
}
}
接收进程部份代码:
while(1)
{
sem_p(semid2); //semid2进行p操作,保护共享区
memset(buff, 0, MAX_SHEARE_MEM_SIZE);
strncpy(buff, sharmem, MAX_SHEARE_MEM_SIZE); //从共享内存区取出数据
printf("receive from you friend : %s\n", buff);
if(!strncmp(buff, "quit", 4))
{
del_sem(semid1);
del_sem(semid2);
break;
}
sem_v(semid1); //semid1进行v操作,释放对共享区的保护
}
//删除共享内存区
if((shmctl(shmid1, IPC_RMID, NULL)) < 0)
{
perror("shmctl");
}
共享内存区是可用IPC形式中最快的。一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核(这里说的不涉及内核的含义是:进程不再通过执行任何进入内核的系统调用来彼此传递数据)。然而往该共享内存区存放信息或从中取走信息的进程间通常需要某种形式的同步,同步的方式有多种,比如:信号量、互斥锁等等。
以下两图分别描述了读写消息时,一个要进入内核,而一个不进入内核的情况:
对于System V共享内存区,内核维护如下的信息结构,它定义在<sys/shm.h>头文件中:
struct shmid_ds{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* segment size */
.
.
.
};
有了以上的知识,那么如何来对共享内存进行操作呢,以下就开始讲解如何来操作:
创建一个新的共享内存区,或者访问一个已存在的共享内存区。
#include <sys/shm.h>
int shmget(key_t key, size_t size, into flag);
size以字节为单位指定内存区的大小。当实际操作为创建一个新的共享内存区时,必须指定一个不为0的size值。如果实际操作为访问一个已存在的共享内存区,那么size应为0。
oflag为读写权限值的组合。它还可以与IPC_CREAT或IPC_CREAT|IPC_EXCL按位或。
当实际操作为创建一个共享内存区时,该内存区被初始化为size字节的0。
由shmget创建或打开一个共享内存区后,通过调用shmat把它附接到调用进程的地址空间。
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int flag);
shmid是由shmget返回的标识符。Shmat的返回值是所指定的共享内存区在调用进程内的起始地址。确定这个地址的规则如下:
如果shmaddr是一个空指针,那么系统替调用者选择地址。(这个是推荐的方法)
如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND:
如果没有指定SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址;
如果指定了SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址向下舍入一个SHMLBA常值。
当一个进程完成共享内存区的使用时,它可调用shmdt断接这个内存区。
#include <sys/shm.h>
int shmdt(const void *shmaddr);
当一个进程终止时,它当前附接着的所有共享内存区都自动断接掉。
注意:本函数调用并不删除所指定的共享内存区。
shmctl提供了对一个共享内存区的多种操作。
#icnldue <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buff);
该函数提供了三个命令:
IPC_RMID 从系统中删除由shmid标识的共享内存区并拆除它。
IPC_SET 给所描写的共享内存区设置其shmid_ds结构的某些成员。
IPC_STAT 向调用者返回所指定共享内存区当前的shmid_ds结构。
以下是共享内存结合信号量进行操作的部份代码:
发关进程的部份代码:
//创建一个共享内存区
if((shmid1 = shmget(shmkey1, MAX_SHEARE_MEM_SIZE, IPC_CREAT|0666)) < 0)
{
perror("shmget");
}
//把共享内存区附接到调用进程的地址空间
if((sharmem = shmat(shmid1, NULL, 0)) < 0)
{
perror("shmat");
}
while(1)
{
sem_p(semid1); //semid1进行p操作,保护共享区
memset(buff, 0, MAX_SHEARE_MEM_SIZE);
printf("Input ou want to say with you friend!\n");
fgets(buff, MAX_SHEARE_MEM_SIZE, stdin);
if(strncmp(buff, "quit", 4))
{
//往共享内存区放入数据
strncpy(sharmem, buff, MAX_SHEARE_MEM_SIZE);
sem_v(semid2); //semid2进行v操作,释放对共享区的保护
}
else
{
strncpy(sharmem, buff, MAX_SHEARE_MEM_SIZE);
sem_v(semid2);
break;
}
}
接收进程部份代码:
while(1)
{
sem_p(semid2); //semid2进行p操作,保护共享区
memset(buff, 0, MAX_SHEARE_MEM_SIZE);
strncpy(buff, sharmem, MAX_SHEARE_MEM_SIZE); //从共享内存区取出数据
printf("receive from you friend : %s\n", buff);
if(!strncmp(buff, "quit", 4))
{
del_sem(semid1);
del_sem(semid2);
break;
}
sem_v(semid1); //semid1进行v操作,释放对共享区的保护
}
//删除共享内存区
if((shmctl(shmid1, IPC_RMID, NULL)) < 0)
{
perror("shmctl");
}
武汉电脑培训培训相关新闻
武汉电脑培训相关课程
- 暑假武汉网页设计培训班、武汉网页设计全能班培训、武汉网站优化…
- 武汉网页设计全能班培训、武汉网页设计培训班、武汉网站优化培训…
- 武汉网页设计培训班、武汉网页设计全能班培训、武汉网站优化培训…
- 武汉网页设计美工培训、武汉网页设计师培训、武汉平面设计培训、…
- 武汉网页短期速成班培训、武汉网站优化培训、武汉网页全科班、武…
- 武昌武汉办公基础培训、武汉办公精品班培训、武昌办公文秘培训、…
- 武汉办公文员培训、武汉计算机短期培训、武昌办公软件培训学校、…
- 武汉办公自动化培训学校、武昌办公文秘培训、武昌计算机基础培训…
- 武汉高级办公文秘培训、武昌高级商务文秘班、武昌办公基础培训、…
- 武汉计算机短期培训、武昌办公软件培训学校、武昌高级办公软件培…
- 武汉平面设计短期培训、武汉平面设计培训、武汉平面广告设计培训…
- 武汉ps高级培训班、武汉平面设计培训、武汉平面广告设计培训、武…
- 武汉ps短期培训、武昌ps培训、武汉平面设计培训、武汉平面广告设…
- 武汉平面广告高级班、武汉平面设计培训、武汉平面广告设计培训、…