共享内存share memory
是一种通信效率最高的进程间通信方式,
进程间通信时直接访问内存,不需要进行数据的拷贝

ipcs    -m    查看当前共享内存
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
步骤:1. ftok2. shmget3. shmat4.进程间通信fork5. shmdt6. shmct1
int shmget(key_t key,size_t size,int shmf1g);
功能:创建一个共享内存
参数:
key: ftok的返回值   or    IPC_PRIVATE
size:内存大小    (自己写大小,1024bytes 4096bytes都行)
shmf1g:
          IPC_CREAT |0666
返回值:
    成功: shmid
    失败:-1
void *shmat(int shmid,const void *shmaddr,intshmf1g);
功能:映射
参数:
    shmid: shmget的返回值
    shmaddr:NULL 自动完成映射
    shmf1g:
                SHM_RDONLY:只读
                      0:读写
返回值:
    成功:地址
    失败:NULL
int shmdt(const void *shmaddr);
功能:解除映射
参数:
    shmaddr: shmat函数的返回值
返回值:
    成功:0
    失败:-1
int shmctl(int shmid,int cmd,struct shmid_dsbuf);
功能:控制函数
参数:
    shmid: shmget函数的返回值
    cmd: IPC_RMID 删除共享内存
    buf: NULL
返回值:
    成功:0
    失败:-1
例:亲缘进程的内存共享
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include csys/shm.h>int main(int argc,const char *arg[]{key_t key = ftok( "/",1);if (key --1){perror("ftok");return -1;}int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid == -1){perror("shmget");goto XXX;}printf("shmid: %d\n",shmid);system("ipcs -m");char *p = shmat(shmid,NULL,0);if(p == NULL){perror("shmat");goto XXX;}//forkpid_tpid = fork( );if(pid <0){perror("fork");goto XXX;}else if(pid == 0){//子进程写操作char buf[64]= {0};while(1){gets(buf);strcpy(p, buf);if(strncmp( buf, "quit",4) == 0){break;}}
}
else{
//父进程读操作waitpid (-1,NULL,WNOHANG);while(1){printf("p=%s\n",p);sleep(1);if(strncmp(p,"quit",4) == 0){break;}}}int ret = shmdt(p);if(ret == 1){perror("shmdt");goto XXX;}ret = shmctl(shmid,IPC_RMID,NULL);if(ret == -1){perror("shmctl");goto XXX;}
XXX:sleep(2);char str[100] = {0};sprintf(str,"ipcrm -m%d",shmid);system(str);system("ipcs -m");return 0;
}
消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
步骤:
1. ftok
2. msgget
3.进程间通信
4. msgsnd
5. msgrcv
6. msgctl
int msgget(key_t key,int msgf1g);
功能:创建消息队列
参数:
    key: ftok函数的返回值  or  IPC_PRIVATE
    msgf1g:IPC_PRIVATE|0666
返回值:
    成功:key
    失败:-1
//结构体

struct msgbuf{long mtype;    /*message type,must be 0*/char mtext[N];    /*message data */};

struct msgbuf msg    //定义结构体变量
int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgf1g);
功能:发送数据
参数:
    msgid:  msgget函数的返回值
    msgp:  &msg
    msgsz:  发送正文的长度
            sizeof(msg) - sizeof(long)
             结构体长度  -  
    msgf1g:
            IPC_NOWAIT:非阻塞
            0:阻塞
返回值:
    成功:0
    失败:-1
struct msgbuf msg;
ssize_t msgrcv(int msgid,void *msgp,size_t msgsz,long msgtyp,int msgf1g);
功能:接收数据
参数:
    msgid: msgget函数的返回值
    msgp: &msg
    msgsz: 发送正文的长度
            sizeof(msg) - sizeof(long)
    msgtyp:消息的类型
    msgf1g:
            IPC_NOWAIT:非阻塞
            0:阻塞
返回值:
    成功:接收消息的长度
    失败:-1
int msgct1(int msgid,int cmd,struct msqid_ds *buf);
功能:删除消息队列
参数:
    msgid: msgget函数的返回值
    cmd: IPC_RMID
    buf: NULL
返回值:
    成功:0
    失败:-1
信号灯集
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
步骤:
    1. ftok
    2. hmget
    3. shmat
   *4. semget
   *5. semctl
    6.进程间通信
   *7. semop
   *8. semct1
    9. shmdt
    10. shmctl
int semget(key_t key,int nsems,int semf1g);
功能:创建信号灯集
参数:
    key:ftok的返回值  or IPC_PRIVATE
    nsems:设置的信号灯的数目
semf1g:
    IPC_CREAT |0666
返回值:
    成功: semid
    失败: -1
union semun {int val; /*value for SETVAL*/struct semid_ds *buf;unsigned short *array;struct seminfo *__buf;};

int semctl(int semid, int semnum,int cmd,...);
功能:信号灯集控制函数
参数:
semid: semget的返回值
semnum:要设置的信号灯的编号
cmd:
    IPC_RMID:删除信号灯集
    SETVAL:设置信号灯
    ...:共用体的变量  or  不写返回值:
返回值:
    成功:0
    失败:-1
编号                初值
     0      sem0      0     
     1      sem1      1   
     子进程:写入
       sem1:-1  
       //write       
       sem0:+1  
         父进程:读取
       sem0:-1
       //read  
       sem1:+1
int semop(int semid, struct sembuf *sops, unsigned nsops);     
功能:对信号灯进行PV操作  -1  +1     
参数:
  semid: semget的返回值
    sops: 结构体的变量的地址
    struct sembuf{
        unsigned short sem_num;  /* semaphore number 信号灯的编号  */
        short sem_op;   /* semaphore operation 信号灯操作-1 +1*/
        short sem_flg;  /* operation flags 0:阻塞 */
    }
    nsops: 信号灯的个数 默认就是1
返回值:
    成功:0
    失败:-1
例:用信号灯集实现先写后读效果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>union semun {int val;  /* Value for SETVAL */struct semid_ds *buf;  unsigned short  *array;struct seminfo  *__buf;
};/*
struct sembuf{unsigned short sem_num;short sem_op;short sem_flg;
};
*/int main(int argc, const char *argv[])
{key_t key = ftok("/", 1);if(key == -1){perror("ftok");return -1;}int shmid = shmget(key, 1024, IPC_CREAT|0666);if(shmid == -1){perror("shmget");goto xxx;}printf("shmid:%d\n",shmid);system("ipcs -m");char *p = shmat(shmid, NULL, 0);if(p == NULL){perror("shmat");goto xxx;}//加入信号灯集来控制共享内存int semid = semget(key, 2, IPC_CREAT|0666);if(semid == -1){perror("semget");goto xxx;}//设置初值union semun sem0 = {0};union semun sem1 = {1};//设置编号semctl(semid, 0, SETVAL, sem0);semctl(semid, 1, SETVAL, sem1);//fork创建新进程pid_t pid = fork();if(pid < 0){perror("fork");goto xxx;}else if(pid == 0){//子进程 写操作char buf[64] = {0};struct sembuf sem0; //定义一个信号灯sem0sem0.sem_num = 1; //编号sem0.sem_op = -1; //PV操作 +1 -1sem0.sem_flg = 0;struct sembuf sem1;sem1.sem_num = 0;sem1.sem_op = 1;sem1.sem_flg = 0;while(1){semop(semid, &sem0, 1);gets(buf);strcpy(p, buf);if(strncmp(buf, "quit", 4) == 0){break;}semop(semid, &sem1, 1);}}else{//父进程 读操作waitpid(-1, NULL, WNOHANG);struct sembuf sem0;sem0.sem_num = 0;sem0.sem_op = -1;sem0.sem_flg = 0;struct sembuf sem1;sem1.sem_num = 1;sem1.sem_op = 1;sem1.sem_flg = 0;while(1){semop(semid, &sem0, 1);printf("p=%s\n", p);sleep(1);if(strncmp(p, "quit", 4) == 0){break;}semop(semid, &sem1, 1);}}int ret = semctl(semid, 0|1, IPC_RMID);if(ret == -1){perror("semctl");goto xxx;}ret = shmdt(p);if(ret == -1){perror("shmdt");goto xxx;}ret = shmctl(shmid, IPC_RMID, NULL);if(ret == -1){perror("shmctl");goto xxx;}xxx:    sleep(2); //防止出错char str[100] = {0};sprintf(str, "ipcrm -m %d", shmid);system(str);system("ipcs -m");return 0;
}

共享内存,信号,信号灯集相关推荐

  1. 进程间通信方式(三)-- IPC对象(消息队列、共享内存、信号灯集)

    IPC对象 1. IPC对象 2. 查看IPC对象命令 3. 消息队列 3.1 概念 3.2 相关函数 3.2.1 msgget() 创建或者打开消息队列 3.2.2 ftok() 获取键值 3.2. ...

  2. linux 进程间通信及makefile 无名管道/有名管道/共享内存/信号/消息队列

    http://www.voidcn.com/article/p-hxvuiypm-mr.html https://www.cnblogs.com/wuyida/archive/2013/02/03/6 ...

  3. 进程间的通信方式(管道,消息队列,共享内存,信号)

    目录 了解 使用管道来通信 无名管道 有名管道 消息队列 key 键值生成 共享内存 信号 信号概述 信号如何携带消息 信号发送函数: 信号量 了解 创建进程后实现父子通讯的连接. 我们希望有一个管道 ...

  4. java共享内存_Java共享内存

    1   共享内存对应应用开发的意义 对熟知UNIX系统应用开发的程序员来说,IPC(InterProcess Communication)机制是非常熟悉的,IPC基本包括共享内存.信号灯操作.消息队列 ...

  5. linux消息队列消息清空函数,ipcrm命令_Linux ipcrm 命令用法详解:删除消息队列、信号集、或者共享内存标识...

    ipcrm命令用来删除一个或更多的消息队列.信号量集或者共享内存标识. 语法ipcrm [ -m SharedMemoryID ] [ -M SharedMemoryKey ] [ -q Messag ...

  6. Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存

    Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:<linux编程从入门到精通>,<Linux C程序设计大全>,<unix环境高级编程> ...

  7. Linux(信号,进程间通信)共享内存,信号量,消息队列

    信号(signal) 1.1 什么是信号? 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式 1.2 信号的来源 硬件 [1] 用户在终端按下某些键时,终端驱动程序会发送信号给前台进程 ct ...

  8. Linux下进程间通信方式之管道、信号、共享内存、消息队列、信号量、套接字

    /* 1,进程间通信 (IPC ) Inter-Process Communication比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息.2,linux下IPC机制的分类:管道.信号. ...

  9. Linux进程间通信(管道、消息队列、共享内存、信号、信号量)

    目录 Linux进程间通信概述 1.管道 无名管道(pipe) 有名管道(fifo) 2.消息队列(msg) 消息队列的通信原理 消息队列相关api 消息队列收发数据 键值生成 消息队列移除 3.共享 ...

  10. 进程间通信IPC(二)(共享内存、信号、信号量)

    共享内存: 共享内存就是允许两个或多个进程共享一定的存储区.就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针.当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更 ...

最新文章

  1. springboot +element-axios跨域请求
  2. 快手超大规模集群调度优化实践
  3. 互联网产品发布之灰度发布
  4. linux 进程内存开销,linux下查看最消耗CPU、内存的进程
  5. 怎样避免MYSQLD被OOM-KILLER杀死?
  6. java 记事本全选_java 编写的记事本程序怎么实现复制 黏贴 剪切 全选的功能 ?...
  7. AutoCAD ObjectARX和RealDWG的基本数据操作
  8. zabbix-server添加了网络设备模板导致boot.log占满根目录不能ssh登陆
  9. 御剑仙侠服务器维护,修仙无双御剑仙侠
  10. 高等数学中一些数学定理和公式
  11. 局域网计算机加密共享文件,局域网共享文件,小编教你局域网共享文件怎么加密...
  12. Configured
  13. 有些打不开的国外网页
  14. 计算机毕业设计ssm基于SSM的美妆分享网站vf952系统+程序+源码+lw+远程部署
  15. 未来教育计算机二级2020年9月有几套题,未来教育】2021年9月全国计算机二级office题库国二计算机等级考试上机考试真题计算机二级msoffice2021年考试备考三月教材九2016...
  16. JAVA中初始化线程的两种方法_java中最简单的方式新起一个线程
  17. python程序员加班多吗_程序员加班严重,如何才能不加班
  18. 超级个人计算机用于股票交易,近五个交易日超级计算机概念股市复盘,哪些股票值得关注(2月23日)...
  19. 树莓派4B入手体验及配置
  20. java 爬虫框架nutch_网络爬虫(2)-- Java爬虫框架

热门文章

  1. 如何利用SPSS进行秩和检验
  2. MXF Operational Pattern 1a (OP1a)
  3. AliDDNS 阿里云动态域名服务 实用工具
  4. OpenSSL密码库算法笔记——第2.4章 三种模运算的比较
  5. vue3.2 lottie-web动画+引入json动画
  6. word中在分页符后设置标题的段前间距
  7. 软件智能:aaas系统中的数学程序与技术服务之4 序篇之 综述2 词典lexicon
  8. 如何在Excel里输入可以打钩的选择框?
  9. 盘点2020年最好用的7款3D游戏建模软件
  10. 计算两向量的旋转角(转)