当前位置: 技术问答>linux和unix
unix下通过(共享内存) 进行 (进程间通讯)???
来源: 互联网 发布时间:2015-01-26
本文导语: 两个进程间通过共享内存是怎么通讯的?能不能详细说说,并有没有什么相应书籍or资料or例程看看。 小弟新人,先谢谢了! | 以前接触过,不熟,知道大概: 共享内存是System V的进程通...
两个进程间通过共享内存是怎么通讯的?能不能详细说说,并有没有什么相应书籍or资料or例程看看。
小弟新人,先谢谢了!
小弟新人,先谢谢了!
|
以前接触过,不熟,知道大概:
共享内存是System V的进程通讯方式之一,大概的过程是
先从内存中开辟出一块,并赋予一个标示符,然后,多个程序之间就可以通过
他进行通讯,需要注意的是,使用这种方式一般需要结合"信号量"来进行管理,防止出现同时写以及死锁(就是典型的供应者/消费者问题)。
共享内存是System V的进程通讯方式之一,大概的过程是
先从内存中开辟出一块,并赋予一个标示符,然后,多个程序之间就可以通过
他进行通讯,需要注意的是,使用这种方式一般需要结合"信号量"来进行管理,防止出现同时写以及死锁(就是典型的供应者/消费者问题)。
|
这是system V的IPC三大法宝之一:
共享虚空间的若干部分,然好通过直接读写来通信。
shmget 建立新的共享存储区
shmdt shmat 分别将之和一个进程空间附加和断开
shmctl 对参数进行控制
****以下是unix的shmget实现的源代码*****************************
shmget()
{
register struct a {
key_t key;
int size,
shmflg;
}*uap = (struct a*)u.u_ap;
register struct shmid_ds *sp;
int s;
int size,ptsize;
if((sp = ipcget(uap->key,uap->shmflg,shmem,shminfo.shmmni,sizeof(*sp),&s))==NULL)
return;
if(s){
if(uap->sizesize>shminfo.shmmax){
u.u_error = EINVAL;
sp->shm_perm.mode = 0;
return;
}
size = btoc(uap->size);
if(shmtot+size >shminfo.shmall){
u.u_error = ENOMEM;
sp->shm_perm.mode = 0;
return;
}
sp->shm_segsz =uap->size;
ptsize = btoc(sizeof(struct pt_entry)*size);
sp->shm_ptbl = (struct pt_entry *)sptalloc(ptsize,PG_V|PG_KW,0);
if(sp->shm_ptbl == NULL ||
memall(sp->shm_ptbl,size)==0)
u.u_error = ENOMEM;
sp->shm_perm.mode=0;
if(sp->shm_perm.mode = 0;
sptfree(sp->shm_ptbl,ptsize,1);
return;
}
maxmem-=(ptsize+size);
shmtot+=size;
sp->shm_perm.mode|=SHM_CLEAR;
sp->shm_nattch = sp->shm_cnattch = 0;
sp->shm_atime = sp->shm_dtime = 0;
sp->shm_ctime = time;
sp->shm_lpid =0;
sp->shm_cpid =u.u_procp->p_pid;
}else
if(uap->size&&uap->sizeshm_segsz){
u.u_error = EINVAL;
return;
}
u.u_ravl1 = sp->shm_perm.seq*shminfo.shmmni+(sp-shmem);
}
共享虚空间的若干部分,然好通过直接读写来通信。
shmget 建立新的共享存储区
shmdt shmat 分别将之和一个进程空间附加和断开
shmctl 对参数进行控制
****以下是unix的shmget实现的源代码*****************************
shmget()
{
register struct a {
key_t key;
int size,
shmflg;
}*uap = (struct a*)u.u_ap;
register struct shmid_ds *sp;
int s;
int size,ptsize;
if((sp = ipcget(uap->key,uap->shmflg,shmem,shminfo.shmmni,sizeof(*sp),&s))==NULL)
return;
if(s){
if(uap->sizesize>shminfo.shmmax){
u.u_error = EINVAL;
sp->shm_perm.mode = 0;
return;
}
size = btoc(uap->size);
if(shmtot+size >shminfo.shmall){
u.u_error = ENOMEM;
sp->shm_perm.mode = 0;
return;
}
sp->shm_segsz =uap->size;
ptsize = btoc(sizeof(struct pt_entry)*size);
sp->shm_ptbl = (struct pt_entry *)sptalloc(ptsize,PG_V|PG_KW,0);
if(sp->shm_ptbl == NULL ||
memall(sp->shm_ptbl,size)==0)
u.u_error = ENOMEM;
sp->shm_perm.mode=0;
if(sp->shm_perm.mode = 0;
sptfree(sp->shm_ptbl,ptsize,1);
return;
}
maxmem-=(ptsize+size);
shmtot+=size;
sp->shm_perm.mode|=SHM_CLEAR;
sp->shm_nattch = sp->shm_cnattch = 0;
sp->shm_atime = sp->shm_dtime = 0;
sp->shm_ctime = time;
sp->shm_lpid =0;
sp->shm_cpid =u.u_procp->p_pid;
}else
if(uap->size&&uap->sizeshm_segsz){
u.u_error = EINVAL;
return;
}
u.u_ravl1 = sp->shm_perm.seq*shminfo.shmmni+(sp-shmem);
}