分享

Linux进程通信 共享内存+信号量

 夜海星空 2009-12-14

/*client.c:从共享内存中读出People*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int main()
{
 int semid;
 int shmid;
 key_t semkey;
 key_t shmkey;
 semkey=ftok("server.c",0);
 shmkey=ftok("client.c",0);
 
 struct People{
  char name[10];
  int age;
 };

 /*读取共享内存和信号量的IPC*/ 
 semid=semget(semkey,0,0666);
 if(semid==-1)
 printf("creat sem is fail\n");
 shmid=shmget(shmkey,0,0666);
 if(shmid==-1)
 printf("creat shm is fail\n");
 
 /*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/
 struct People * addr;
 addr=(struct People*)shmat(shmid,0,0);
 if(addr==(struct People*)-1)
 printf("shm shmat is fail\n");
 
 /*信号量的P操作*/
 void p()
 {
  struct sembuf sem_p;
  sem_p.sem_num=0;
  sem_p.sem_op=-1;
  if(semop(semid,&sem_p,1)==-1)
  printf("p operation is fail\n");  
 }
 
 /*信号量的V操作*/
 void v()
 {
  struct sembuf sem_v;
  sem_v.sem_num=0;
  sem_v.sem_op=1;
  if(semop(semid,&sem_v,1)==-1)
  printf("v operation is fail\n");
 }
 
 /*从共享内存读出数据*/
 p();
 printf("name:%s\n",addr->name);
 printf("age:%d\n",addr->age);
 v();
 
 /*将共享内存与当前进程断开*/
 if(shmdt(addr)==-1)
 printf("shmdt is fail\n");
 
 /*IPC必须显示删除。否则会一直留存在系统中*/
 if(semctl(semid,0,IPC_RMID,0)==-1)
 printf("semctl delete error\n");
 if(shmctl(shmid,IPC_RMID,NULL)==-1)
 printf("shmctl delete error\n");
}
 
 
 
/*server.c:向共享内存中写入People*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main()
{
 struct People{
  char name[10];
  int age;
 };
 
 int semid;
 int shmid;
 key_t semkey;
 key_t shmkey;
 semkey=ftok("server.c",0);
 shmkey=ftok("client.c",0);
 
 /*创建共享内存和信号量的IPC*/
 semid=semget(semkey,1,0666|IPC_CREAT);
 if(semid==-1)
 printf("creat sem is fail\n");
 shmid=shmget(shmkey,1024,0666|IPC_CREAT);
 if(shmid==-1)
 printf("creat shm is fail\n");
 
 /*设置信号量的初始值,就是资源个数*/
 union semun{
  int val;
  struct semid_ds *buf;
  ushort *array;
 }sem_u;
 
 sem_u.val=1;
 semctl(semid,0,SETVAL,sem_u);
 
 /*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/
 
 struct People * addr;
 addr=(struct People*)shmat(shmid,0,0);
 if(addr==(struct People*)-1)
 printf("shm shmat is fail\n");
 
 /*信号量的P操作*/
 void p()
 {
  struct sembuf sem_p;
  sem_p.sem_num=0;
  sem_p.sem_op=-1;
  if(semop(semid,&sem_p,1)==-1)
  printf("p operation is fail\n");  
 }
 /*信号量的V操作*/
 void v()
 {
  struct sembuf sem_v;
  sem_v.sem_num=0;
  sem_v.sem_op=1;
  if(semop(semid,&sem_v,1)==-1)
  printf("v operation is fail\n");
 }
 
 /*向共享内存写入数据*/
 p();
 strcpy((*addr).name,"xiaoming");
/*注意:①此处只能给指针指向的地址直接赋值,不能在定义一个  struct People people_1;addr=&people_1;因为addr在addr=(struct People*)shmat(shmid,0,0);时,已经由系统自动分配了一个地址,这个地址与共享内存相关联,所以不能改变这个指针的指向,否则他将不指向共享内存,无法完成通信了。
注意:②给字符数组赋值的方法。刚才太虎了。。*/
 (*addr).age=10;
 v();
 
 /*将共享内存与当前进程断开*/
 if(shmdt(addr)==-1)
 printf("shmdt is fail\n"); 
 
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多