• 信号灯的典型应用




    二值信号灯:值为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;
    }
  • 相关阅读:
    进程的Binder线程池工作过程
    Binder系列—开篇
    shell脚本使用技巧3--调试
    shell脚本使用--sleep
    shell脚本使用技巧2
    linux添加环境变量
    shell脚本学习1(Linux脚本攻略)
    c++语言的设计和演化---在线函数
    vim常用快捷键
    git常用命令
  • 原文地址:https://www.cnblogs.com/vonyao/p/3614338.html
Copyright © 2020-2023  润新知