CSDN博客

img maisuiki

共享内存和信号量(实例)

发表于2008/9/28 21:47:00  1946人阅读

分类: it

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/sem.h>
#include "structs.h"
/*typedef struct{
 char name[10];
 int age;
}People;
*/
//声明联合体
union semun{
int val;
struct semid_ds *buf;
unsigned short int *array;
};

int main(int argc,char **argv){
        SHM *p_map;
 int shm_id;
        int i;
        char temp;
        int key;
        //People *p_map;
        char *name = "/dev/shm/myshm2";
 int value;
 int sem_id;
 union semun options;
 struct sembuf lock_it;

        key = ftok(name,0);                        //获得key值,用到了ftok函数
        if (key==-1){
                perror("ftok error");
        }
 
 sem_id = semget(key,1,IPC_CREAT|0666);        //通过key获得信号量id
 printf("sem_id=%d/n",sem_id);
 if(-1==sem_id){
  printf("create semaphore error/n");
  exit(-1);
 }
 options.val =1;                                 //操作联合体,使得初始的信号量为1
 semctl(sem_id,0,SETVAL,options);                //设置索引为0的位置的信号量

  i = semctl(sem_id,0,GETVAL,options);             //获取 索引为 0的 位置的信号量 i
 printf("%d/n",i);

        shm_id = shmget(key,1024,IPC_CREAT);               //通过key及是shmget函数创建共享内存
        if (shm_id == -1){
                perror("shmget error");
                return;
        }
 p_map =(SHM*)shmat(shm_id,NULL,0);                //通过shmat操作共享内存
 
 lock_it.sem_num =0;                                 //操作信号量,使信号量减一变成0
 lock_it.sem_op = -1;
 lock_it.sem_flg = IPC_NOWAIT;
 semop(sem_id,&lock_it,1);
 
 i = semctl(sem_id,0,GETVAL,0);                    //得到信号量为0
 printf("xiu gai hou de i %d/n",i);
        p_map =(SHM*)shmat(shm_id,NULL,0);
 
 strcpy(p_map->chara,"zhangsan");             //对 共享内存中的结构体进行操作
        p_map->inta=20;
        printf("%d/n",p_map->inta);
 printf("%s/n",p_map->chara);
 
 lock_it.sem_num = 0;                  //操作完毕后 信号量加1 ,便于其他进程使用
 lock_it.sem_op = +1;
 lock_it.sem_flg = IPC_NOWAIT;
 semop(sem_id,&lock_it,1);
 
 i = semctl(sem_id,0,GETVAL,0);
 printf("zai ci xiu gai hou de i %d/n",i);
        //if (shmdt(p_map)==-1){
          //      perror("detach error");
        //};
 //exit(0);

}
或者可以把以上程序看成是一个  服务器 ,接下来写一个读共享内存中数据的客户端


#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <sys/sem.h>
#include "structs.h"

/*typedef struct{
 char name[10];
 int age;
}People;
*/
union semun{
 int val;
 struct semid_ds*buf;
 unsigned short *array;
};
main(int argc,char** argv){
 int shm_id;
 int i;
 int sem_id;
 key_t key;
 SHM *p_map;
// p_map = (SHM*)malloc(sizeof(People));
 union semun options;
 struct sembuf lock_it;
 char *name = "/dev/shm/myshm2";
 key = ftok(name,0);
 if(key==-1){
  perror("ftok error/n");
 }
 sem_id = semget(key,0,0);            //对已存在  信号量进行操作,参数不一样 ,是0,0
 semctl(sem_id,0,SETVAL,options);
 i = semctl(sem_id,0,GETVAL,0);
 shm_id = shmget(key,0,0);               //对已存在的共享内存进行操作,参数与创建共享内存时不一样
 if(shm_id == -1){
  perror("shmget error/n");
  return;
 }
 lock_it.sem_num = 0;  //等待函数,等到flg为1时,即信号量为1时,才能对共享内存进行操作
 lock_it.sem_op = 0;
 lock_it.sem_flg = 1;
 semop(sem_id,&lock_it,1);
 
 i = semctl(sem_id,0,GETVAL,0);
 while(1){
  if(i==1){
   lock_it.sem_num = 0;  //当判断信号量 i ==1 时,进入共享内存,并马上操作信号量-1变成0,使得其他进程阻塞
   lock_it.sem_op = -1;
   lock_it.sem_flg = IPC_CREAT;
   semop(sem_id,&lock_it,1);
  // p_map = (SHM*)malloc(sizeof(SHM));
   p_map = (SHM*)shmat(shm_id,NULL,0);
 
 //p_map = (People*)malloc(sizeof(People));
   printf("%s/n",p_map->chara);   //读取共享内存中的数据
   printf("%d/n",p_map->inta);
   lock_it.sem_num = 0;  //读取完毕后,再把信号量加1,便于其他进程使用
   lock_it.sem_op = 1;
   lock_it.sem_flg = IPC_CREAT;
   semop(sem_id,&lock_it,1);
   exit(0);
  }else{
   continue;           // 如果信号量不为0,则继续等待
  }
 }
}

 


 

0 0

相关博文

我的热门文章

img
取 消
img