zoukankan      html  css  js  c++  java
  • 信号灯的典型应用



    二值信号灯:值为0或1.与互斥锁类似,资源可用时值为1,不可用时值为0。
    程序如下:
    读端
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <errno.h>
    #include <sys/sem.h>
    #include <string.h>
    #include <strings.h>
    int wait(void)
    {
         int semid = -1;
         int ret = -1;
         key_t key = ftok("/home",2);
         if ( -1 == key )
         {
              perror("ftok");
              return -1;
         }
         semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
         if ( -1 == semid )
         {
              if( EEXIST == errno )
              {
                   semid = semget(key,2,0666);
                   if (-1 == semid )
                   {
                        perror("semget");
                        return -1;
                   }
              }else
              {
                   perror("semget");
                   return -1;
              }
         }
         struct sembuf buf;
         bzero(&buf,sizeof(struct sembuf));
         buf.sem_num = 0;
         buf.sem_op = -1;//分配资源,p操作
         buf.sem_flg = 0;
         ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时分配资源。使资源不可用。锁住
         if ( -1 == ret )
         {
              perror("semop");
              return -1;
         }
    }


    char *addr=NULL;
    void fun(int arg)
    {
         printf("%s ",addr);
    }    
    int main(int argc,char **argv)
    {
         int ret = -1;
         int shmid = -1;
         //char *addr = NULL;

         signal(2,fun);
         key_t key = ftok("/",1);//获得key值
         if ( -1 == key )
         {
              perror("ftok");
              return -1;
         }
         shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//设置共享内存大小为4096
         if ( -1 == shmid )
         {
              if (EEXIST == errno)
              {
                   shmid = shmget(key,4096,0666);
                   if (-1 == shmid)
                   {
                        perror("shmget 2");
                        return -1;
                   }
              }
              else
              {
                   perror("shmget");
              }
         }
         addr = shmat(shmid,NULL,0);//获得共享内存的空间地址
         if ( (void*)(-1) == addr )
         {
              perror("shmat");
              return -1;
         }
         while(1)
         {
              wait();//v操作,分配资源,使共享内存资源减1;使资源不可用
              //--
              printf("%s",addr);
         }
         ret = shmdt(addr);
         if ( -1 == ret )
         {
              perror("shmdt");
              return -1;
         }

         printf("%ld ",key);
         return 0;
    }


    写端
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <errno.h>
    #include <sys/sem.h>
    #include <string.h>
    #include <strings.h>
    int semid = -1;
    int fun_init(void)
    {
         int ret = -1;
         key_t key = ftok("/home",2);//获得key值
         if ( -1 == key )
         {
              perror("ftok");
              return -1;
         }
         semid = semget(key,2,0666|IPC_CREAT|IPC_EXCL);//获得信号灯ID。包含2个信号灯
         if ( -1 == semid )
         {
              if( EEXIST == errno )
              {
                   semid = semget(key,2,0666);
                   if (-1 == semid )
                   {
                        perror("semget");
                        return -1;
                   }
              }else
              {
                   perror("semget");
                   return -1;
              }
         }
    #if 1
         ret = semctl(semid,0,SETVAL,0);//要修改的信号灯编号为0,SETVAL设置信号灯的值,值为0
         if ( -1 == ret )
         {
              perror("semctl");
              return -1;
         }
    #endif
         return 0;
    }
    int post(void)
    {
         int ret = -1;
         struct sembuf buf;
         bzero(&buf,sizeof(struct sembuf));//将buf清零
         buf.sem_num = 0;//要操作的信号灯编号为0
         buf.sem_op = 1;//释放资源,V操作
         buf.sem_flg = 0;//不知什么意思
         ret = semop(semid,&buf,1);//要操作一个信号灯,信号灯编号为0,操作时释放资源,释放资源。使资源可用。解锁,使读端可以读
         if ( -1 == ret )
         {
              perror("semop");
              return -1;
         }
    }
    int main(int argc,char **argv)
    {
         pid_t pid_r = -1;
         int ret = -1;
         int shmid = -1;
         char *addr = NULL;
         key_t key = ftok("/",1);//获得key值
         if ( -1 == key )
         {
              perror("ftok");
              return -1;
         }
         shmid = shmget(key,4096,0666|IPC_CREAT|IPC_EXCL);//共享内存的大小设为4096
         if ( -1 == shmid )
         {
              if (EEXIST == errno)
              {
                   shmid = shmget(key,4096,0666);
                   if (-1 == shmid)
                   {
                        perror("shmget 2");
                        return -1;
                   }
              }
              else
              {
                   perror("shmget");
              }
         }
         addr = shmat(shmid,NULL,0);//将共享内存映射到addr,0为共享内存可读可写
         if ( (void*)(-1) == addr )
         {
              perror("shmat");
              return -1;
         }
         ret = fun_init();//初始化信号灯,灯值为0
         if ( -1 == ret )
         {
              perror("fun_init");
              return -1;
         }
         //0
         while(1)
         {
              fgets(addr,4096,stdin);//获得消息
              //++
              ret = post();//V操作,将值加1.释放资源,外部资源就加1;信号灯的值为1,资源可用
              if( -1 == ret)
              {
                   perror("post");
                   return -1;
              }
         }

         ret = shmdt(addr);//删除共享内存映射后的地址
         if ( -1 == ret )
         {
              perror("shmdt");
              return -1;
         }

         printf("%ld ",key);
         return 0;
    }
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/vonyao/p/3614338.html
Copyright © 2011-2022 走看看