Sample Code on Linux semaphore and shared memory

I wrote a performance improvement algorithm in last month. The algorithm takes Linux semaphore and shared memory to exchange data efficiently.


It was my first time to use Linux semaphore and shared memory. I ransacked the below sample code before writing my code. I think it is worthy to place here for IPC programming starters.


The sample code is copied fromhttp://www.vcgood.com/bbs/forum_posts.asp?tid=2027


#include<sys/types.h>
#include<linux/sem.h>
#include<linux/shm.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>

#define MAXSHM 5  //定义缓冲区数组的下标变量个数


/*        定义3个信号量的内部标识  */

int fullid;
int emptyid;
int mutexid;


/* 主函数  */
int main()
{
   /*  定义2个共享内存的ID  */
   int arrayid;
   int getid;
  

   /*  定义共享内存虚拟地址  */
   int *array;
   int *get;


   /* 创建共享内存  */
  arrayid=shmget(IPC_PRIVATE,sizeof(int) *MAXSHN,IPC_CREAT|0666);
  getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);


  /*  初始化共享内存  */
  array=(int *) shmat(arrayid,0,0);
  get=(int *) shmat(getid,0,0);
  *get=0;


  /* 定义信号量数据结构 */
  struct sembuf  P,V;
  union semun arg;


  /* 创建信号量  */
  fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
  emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
  mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);


  /*初始化信号量 */
  arg.val=0;            //初始时缓冲区中无数据
  if(semctl(fullid,0,SETVAL,arg)==-1)
  perror(”semctl setval error”);
  arg.val=MAXSHM;       //初始时缓冲区中有5个空闲的数组元素
 

  if(semctl(emptyid,0,SETVAL,arg)==-1)
     perror(”semctl setval error”);
  arg.val=1;            //初始时互斥信号为1,允许一个进程进入


  if(semctl(mutexid,0,SETVAL,arg)==-1)
    perror(”semctl setval error”);


  /* 初始化 P  V操作  */
 

  P.sem_num=0;
  P.sem_op=-1;
  P.sem_flg=SEM_UNDO;
  V.sem_num=0;
  V.sem_op=1;
  V.sem_flg=SEM_UNDO;


  /*   生产者进程  */
  if(fork()==0)
  {
    int i=0;
    int set=0;
    while(i<10)
    {
      semop(emptyid,&P,1);         //对 emptyid执行P操作
      semop(mutexid,&P,1);         //对 mutexid执行 P操作
      array[set%MAXSHM]=i+1;
      printf(”Producer put number %d to No.%d/n”,array[set%MAXSHM],set%MAXSHM);
      set++;                       //写计数加1
      semop(mutexid,&V,1);         //对mutexid执行 V 操作
      semop(fullid,&V,1);          //对fullid执行 V 操作
      i++;
    }
    sleep(3);                    //SLEEP 3秒,等待消费者进程执行完毕
    printf(”Poducer if over/n”);
    exit(0);
  }
  else
  {
    /*  消费者A进程  */
    if(fork()==0)
    {
      while(1)
      {
        if(*get==10) break;
        semop(fullid,&P,1);        //对fullid执行 P 操作
        semop(mutexid,&P,1);       //对mutexid执行 P 操作
        printf(”The ConsumerA get number from No.%d/n”,(*get)%MAXSHM);
        (*get)++;                   //读计数加1
        semop(mutexid,&V,1);        //对mutexid执行 V 操作
        semop(emptyid,&V,1);        //对fullid执行 V 操作
        sleep(1);
      }
      printf(”ConsunerA is over/n”);
      exit(0);
    }
    else
    {
      /*消费者B进程  */
      if(fork()==0)
      {
        while(1)
        {
          if(*get==10) break;
          semop(fullid,&P,1);       //对fullid执行 P 操作
          semop(mutexid,&P,1);      //对mutexid执行 P 操作
          printf(”The ConsumerA get number from No.%d/n”,(*get)%MAXSHM);
          (*get)++;                 //读计数加1
          semop(mutexid,&V,1);      //对mutexid执行 V 操作
          semop(emptyid,&V,1);      //对emptyid执行 V 操作
          sleep(1);
        }
        printf(”ConsunerB is over/n”);
        exit(0);
      }
    }
  }


  /*   父进程返回后回收3个子进程  */
  wait(0);
  wait(0);
  wait(0);

 

  /*  断开并撤消2个共享内存  */
  shmdt(array);
  shmctl(arrayid,IPC_RMID,0);
  shmctl(get);
  shmctl(getid,IPC_RMID,0);


  /*   撤消3个信号量集  */
  semctl(emptyid,IPC_RMID,0);
  semctl(fullid,IPC_RMID,0);
  semctl(mutexid,IPC_RMID,0);
  exit(0);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值