Shm,Sem,Msg

shm,sem,msg

    system v :  共享内存  信号量集

    IPC对象操作通用框架:
    0x  ftok
    key值 ==> 申请 ==》读写 ==

》关闭 ==》卸载


    key值:===》唯一键值
    创建方式有三种:

    1、IPC_PRIVATE 固定的私有键值,其值等于 0x0
        一般用于有亲缘关系的进程间使用。

    2、ftok()创建临时键值。
    #include <sys/types.h>
    #include <sys/ipc.h>
                "/etc"                        '!'
    key_t ftok(const char *pathname, int proj_id);
    功能:通过该函数可以将pathname指定的路径用来以
          proj_id生成唯一的临时键值。
    参数:pathname 路径+名称===》任意文件,只要不会
          被删除重建即可。
          proj_id  整形的数字,一般用ASCII码的单字符
          表示与参数1的运算。

    返回值:成功 返回唯一键值
            失败  -1;
    

    ipcs -a 查询共享内存,信号量集,消息队列
    ipcrm -s 删除信号量集
          -m 删除共享内存
    共享内存 ===》效率最高的进程间通信方式

    操作流程:
     key ==》申请对象 ==》映射对象==》读写对象
         ==》撤销映射 ==》删除对象
        

    1、申请对象:shmget()
    #include <sys/ipc.h>
    #include <sys/shm.h>
    ps aux|grep a.out
        share memory get                 IPC_CREAT|0666
    int shmget(key_t key, size_t size, int shmflg);
    功能:使用唯一键值key向内核提出共享内存使用申请
    参数:key  唯一键值
          size  要申请的共享内存大小
          shmflg 申请的共享内存访问权限,八进制表示
          如果是第一个申请,则用IPC_CREAT
          如果要检测是否存在,用IPC_EXCL
    返回值:成功 返回共享内存id,一般用shmid表示
            失败  -1;

            share memory attach
    映射对象:shmat()
    void *shmat(int shmid, const void *shmaddr, int shmflg);
    功能:将指定shmid对应的共享内存映射到本地内存。
    参数:shmid 要映射的本地内存
          shmaddr 本地可用的地址,如果不确定则用NULL,表示
                  由系统自动分配。
          shmflg  
          0,表示读写
          SHM_RDONLY,只读
    返回值:成功 返回映射的地址,一般等于shmaddr
            失败 (void*)-1


    读写共享内存:类似堆区内存的直接读写:
    char * p ;
    
    write(fd,p,);
    read(fd,p,1024);
    memcpy(p,buf,1024);strcpy();
    memset(p,0,1024);== bzero(p,1024);
    memcmp(p,buf,1024); strcmp(a,b);
    
    
    
    字符串:     strcpy(p,"hello");
    字符/数字: 直接赋值

    练习:
        使用共享内存完成两个进程间的进程间通信,
        可以共享一个数字给对方。

    1、共享内存数据的存储方式是拷贝还是剪切?
        拷贝

    2、共享内存的数据如果多次不同进程读写会怎么样?
        同一操作对象,数据没有偏移情况下会覆盖。

    撤销映射:shmdt
    int shmdt(const void *shmaddr);
    功能:将本地内存与共享内存断开映射关系。
    参数:shmaddr 要断开的映射地址。
    返回值:成功  0
            失败  -1;


    删除对象:shmctl
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    功能:修改共享内存属性,也可以删除指定的共享内存对象。
    参数:shmid 要删除的共享内存对象
          cmd IPC_RMID 删除对象的宏
          buff NULL 表示只删除对象。
    返回值:成功 0
            失败 -1

    以上共享内存可能存在如下问题:
    进程1 写入共享内存,如何通知进程2 读共享内存。


    IPC对象之信号量集 ==>sem ===》为了解决共享内存的临界资源访问

    操作流程:
        key ==> 申请信号量集 ==》init==>PV操作 ===》删除信号量

        semaphore
    1、申请信号量  semget()
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>

    int semget(key_t key, int nsems, int semflg);
    功能:通过唯一键值向内核提出信号量申请。
    参数:key 唯一键值
          nsems 要申请的信号量个数
          semflg 申请的信号量的访问权限
    返回值:semid.
            失败 -1;

    2、pv操作;semop

    p ==>sem_wait() ==>sem = sem-1;
    v ==>sem_post() ==>sem = sem+1;

    int semop(int semid, struct sembuf *sops, unsigned nsops);
    功能:修改指定信号量集中信号量的值。
    参数:semid 信号量集id
          sops ==》结构体如下:
          struct sembuf
          {
              unsigned short sem_num;  ///信号量集中信号量的编号,默认以0开始
              short             sem_op;   ///信号量的PV操作,如果改值等于-1则表示p        
                                                                  等于1 则表示v
                                                                  等于0 则表示阻塞

              short          sem_flg;   ///信号量的操作方式 0 表示默认阻塞。
              IPC_NOWAIT and SEM_UNDO.
          };
          nsops 信号量的设置值个数。
    返回值:成功 0
            失败 -1

    通常会将以上函数做如下自定义封装:

    int my_sem_wait(int id,int sem)
    {
        struct sembuf mysem;
        mysem.sem_num = sem;
        mysem.sem_op  = -1;
        mysem.flg      = 0;

        if(semop(id,&mysem,1) < 0)
            return -1;
        else
            return 0;
    }

    int my_sem_post(int id,int sem)
    {
        struct sembuf mysem;
        mysem.sem_num = sem;
        mysem.sem_op  = 1;
        mysem.flg      = 0;

        if(semop(id,&mysem,1) < 0)
            return -1;
        else
            return 0;
    }

    3、信号量的删除
     int semctl(int semid, int semnum, int cmd, ...);
     功能:根据semid删除指定的信号量集
     参数:semid 要删除的信号量集
           semnum 要删除的信号量集中的信号量的编号
           cmd IPC_RMID 删除对象宏
           ...  可变长参数可以不写
    返回值:成功 0
            失败 -1;

    =====================================================

 

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#DESCRIPTION:Resource namespaces pidns01 pidns01 pidns02 pidns02 pidns03 pidns03 pidns04 pidns04 pidns05 pidns05 pidns06 pidns06 pidns10 pidns10 pidns12 pidns12 pidns13 pidns13 pidns16 pidns16 pidns17 pidns17 pidns20 pidns20 pidns30 pidns30 pidns31 pidns31 pidns32 pidns32 mqns_01 mqns_01 mqns_01_clone mqns_01 -m clone mqns_01_unshare mqns_01 -m unshare mqns_02 mqns_02 mqns_02_clone mqns_02 -m clone mqns_02_unshare mqns_02 -m unshare mqns_03 mqns_03 mqns_03_clone mqns_03 -clone mqns_04 mqns_04 mqns_04_clone mqns_04 -clone netns_netlink netns_netlink netns_breakns_ip_ipv4_netlink netns_breakns.sh netns_breakns_ip_ipv6_netlink netns_breakns.sh -6 netns_breakns_ip_ipv4_ioctl netns_breakns.sh -I netns_breakns_ip_ipv6_ioctl netns_breakns.sh -6I netns_breakns_ns_exec_ipv4_netlink netns_breakns.sh -e netns_breakns_ns_exec_ipv6_netlink netns_breakns.sh -6e netns_breakns_ns_exec_ipv4_ioctl netns_breakns.sh -eI netns_breakns_ns_exec_ipv6_ioctl netns_breakns.sh -6eI netns_comm_ip_ipv4_netlink netns_comm.sh netns_comm_ip_ipv6_netlink netns_comm.sh -6 netns_comm_ip_ipv4_ioctl netns_comm.sh -I netns_comm_ip_ipv6_ioctl netns_comm.sh -6I netns_comm_ns_exec_ipv4_netlink netns_comm.sh -e netns_comm_ns_exec_ipv6_netlink netns_comm.sh -6e netns_comm_ns_exec_ipv4_ioctl netns_comm.sh -eI netns_comm_ns_exec_ipv6_ioctl netns_comm.sh -6eI netns_sysfs netns_sysfs.sh shmnstest_none shmnstest -m none shmnstest_clone shmnstest -m clone shmnstest_unshare shmnstest -m unshare shmem_2nstest_none shmem_2nstest -m none shmem_2nstest_clone shmem_2nstest -m clone shmem_2nstest_unshare shmem_2nstest -m unshare shm_comm shm_comm mesgq_nstest_none mesgq_nstest -m none mesgq_nstest_clone mesgq_nstest -m clone mesgq_nstest_unshare mesgq_nstest -m unshare msg_comm msg_comm sem_nstest_none sem_nstest -m none sem_nstest_clone sem_nstest -m clone sem_nstest_unshare sem_nstest -m unshare semtest_2ns_none semtest_2ns -m none semtest_2ns_clone semtest_2ns -m clone semtest_2ns_unshare semtest_2ns -m unshare sem_comm sem_comm utsname01 utsname01 utsname02 utsname02 utsname03_clone utsname03 -m clone utsname03_unshare utsname03 -m unshare utsname04_clone utsname04 -m clone utsname04_unshare utsname04 -m unshare mountns01 mountns01 mountns02 mountns02 mountns03 mountns03 mountns04 mountns04 userns01 userns01 userns02 userns02 userns03 userns03 userns04 userns04 userns05 userns05 userns06 userns06 userns07 userns07 userns08 userns08 # time namespaces sysinfo03 sysinfo03 clock_nanosleep03 clock_nanosleep03 clock_gettime03 clock_gettime03 timens01 timens01 timerfd04 timerfd04
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值