• System V IPC-信号量,共享内存,消息队列


    1、信号量(Semaphores)

        System V的信号量集表示的是一个或多个信号量的集合。内核为每个信号量集维护一个semid_ds数据结构,而信号量集中的每个信号量使用一个无名结构体表示,这个结构体至少包含以下成员:     struct{    

                     unsigned short semval;//信号量值,总是>=0       

                   pid_t sempid;  //上一次操作的pid        …    

              };

        #include <sys/types.h>

       #include <sys/ipc.h>

        #include <sys/sem.h>

        (1)创建或访问信号量         * int semget(key_t key,int nsems,int flag);

        nsems指定信号量集中信号量的个数,如果只是获取信号量集的标识符(而非新建),那么nsems可以为0。flag的低9位作为信号量的访问权限位,类似于文件的访问权限;如果flag中同时指定了IPC_CREAT和IPC_EXCL,那么如果key已与现存IPC对象想关联的话,函数将会返回EEXIST错误。例如,flag可以为IPC_CREAT|0666。

        (2)控制信号量集         * int semctl(int semid,int semnum,int cmd,union semun arg);

        对semid信号量集合执行cmd操作;cmd常用的两个值是:SETVAL初始化第semnum个信号量的值为arg.val;IPC_RMID删除信号量。

        (3)对一个或多个信号量进行操作         * int semop(int semid,struct sembuf *sops,unsigned nsops);

            * struct sembuf{

                  unsigned short sem_num;  //信号量索引

                  short   sem_op;     //对信号量进行的操作,常用的两个值为-1和+1,分别代表P、V操作

                  short   sem_flag;   //比较重要的值是SEM_UNDO:当进程结束时,相应的操作将被取消;同时,如果进程结束时没有释放资源的话,系统会自动释放

               };

    2、共享内存

        共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC。

       #include <sys/ipc.h>

        #include <sys/shm.h>

        (1)创建或访问共享内存         * int shmget(key_t key,size_t size,int shmflg);

        (2)附加共享内存到进程的地址空间

            * void *shmat(int shmid,const void *shmaddr,int shmflg);//shmaddr通常为NULL,由系统选择共享内存附加的地址;shmflg可以为SHM_RDONLY

        (3)从进程的地址空间分离共享内存         * int shmdt(const void *shmaddr); //shmaddr是shmat()函数的返回值

        (4)控制共享内存         * int shmctl(int shmid,int cmd,struct shmid_ds *buf);

            * struct shmid_ds{

                  struct ipc_perm shm_perm;

                  …

              };

        cmd的常用取值有:(a)IPC_STAT获取当前共享内存的shmid_ds结构并保存在buf中(2)IPC_SET使用buf中的值设置当前共享内存的shmid_ds结构(3)IPC_RMID删除当前共享内存

    3、消息队列

        消息队列保存在内核中,是一个由消息组成的链表。

       #include <sys/types.h>

        #include <sys/ipc.h>

        #include <sys/msg.h>

        (1)创建或访问消息队列

        * int msgget(key_t key,int msgflg);

        (2)操作消息队列

           * int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);

        msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小

           * ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg)

    ;     如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值要小于等于msgtype的绝对值。

        (3)控制消息队列         * int msgctl(int msqid,int cmd,struct msqid_ds *buf);

            * struct msqid_ds{

                  struct ipc_perm msg_perm;

                  …

               };

  • 相关阅读:
    将1、2、3..10...变成01、02、03...10...
    idea启动项目时报错
    八锁现象
    友联
    通达OA 任意文件删除结合文件上传导致RCE漏洞复现
    Linux提权
    vulnhub靶机DC2记录
    ThinkPHP5.x 任意代码执行漏洞复现
    SaltStack远程命令执行漏洞复现(CVE-2020-11651、CVE-2020-11652)
    vulnhub靶机DC1记录
  • 原文地址:https://www.cnblogs.com/funnylinux/p/3554747.html
Copyright © 2020-2023  润新知