一江春水向东流

做一个有思想的人,期待与每一位热爱思考的人交流,您的关注是对我最大的支持。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  44 随笔 :: 139 文章 :: 81 评论 :: 0 Trackbacks

共享内存原型
shmid_ds结构
struct shmid_ds{
    struct ipc_perm    shm_perm;
    size_t                   shm_segsz;
    pid_t                    shm_lpid;
    pid_t                    shm_cpid;
    shmatt_t               shm_nattch;
    time_t                   shm_atime;
    time_t                   shm_dtime;
    time_t                   shm_ctime;
    .
};

#include <sys/shm.h>
int shmget (key_t  key, size_t size, int flag);
     成功返回共享存储ID,错误返回-1
int shmctl (int shmid, int cmd, struct shmid_ds,*buf);
     cmd有 IPC_STAT, IPC_SET, IPC_RMID, SHM_LOCK, SHM_UNLOCK

连接到地址空间
void *shmat (int shmid ,const void *addr, int flag);

对共享内存操作结束时,脱离该段
int shmdt (void *addr);

要运行程序,需要在当前目录下建立一个share文件,share是一个空文件,没有任何意义,只是函数ftok需要一个文件名作参数,ftok另一个参数可以为任何数字。

程序运行后,分为父子进程,子进程申请共享内存,然后等待父进程继续执行,父进程首先等待子进程申请到共享内存标识,然后输出共享内存中的内容,为了演示共享内存可以随时更新,程序中在子进程里产生随机数写入共享内存供父进程读取。
代码如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>

#include<time.h>
#include<signal.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>

int shmID;
char * buf;
 
void finalize(int signo)
{
 shmctl(shmID,IPC_RMID,NULL);
 
 exit(0);
}

int main()
{
 int i = 1;  
 key_t shmKey;
 
 signal(SIGINT,finalize);
 signal(SIGTERM,finalize);
 
 if(fork() == 0) //子进程
 {  
  shmKey = ftok("share",16);  //可以使用任何大于0的数字,如果名字和数相同,则产生的key相同。
  if(shmKey == -1)
  {
   printf("创建key出错\n");
   exit(-1);
  }
  
  shmID = shmget(shmKey,20,IPC_CREAT | IPC_EXCL | 0666);
  if(shmID == -1)
  {
   printf("创建共享标识出错\n");
   exit(-1);
  }
  
  sleep(2); //等待父进程执行,好显示第一行为空。
  while(1)
  {
   buf = (char *)shmat(shmID,NULL,0);
   srandom(time(NULL));
   sprintf(buf,"%d",random()); 
   shmdt(buf);  
  }
 }
 else  //父进程
 {
  sleep(1); //让子进程先执行,以建立内存映射。
  
  shmKey = ftok("share",16);  //可以使用任何大于0的数字,如果名字和数相同,则产生的key相同。
  if(shmKey == -1)
  {
   printf("创建key出错\n");
   exit(-1);
  }
  
  shmID = shmget(shmKey,20,0); //0表示如果shmKey映射的不存在则报错。
  if(shmID == -1)
  {
   printf("引用共享标识出错\n");
   exit(-1);
  }
  
  while(1)
  { 
   buf = (char *)shmat(shmID,NULL,0);
   printf("%d. 现在共享内存中的内容为:%s\n",i++,buf);
   shmdt(buf);
   sleep(1);
  }
 } 

 return 0;
}


 

posted on 2008-04-04 23:55 allic 阅读(1491) 评论(0)  编辑  收藏 所属分类: linux/UNIX 应用开发