共享内存

共享内存

核能气质少年 提交于 2019-12-16 01:59:12
采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。 Linux的2.2.x内核支持多种共享内存方式,如mmap()系统调用,Posix共享内存,以及系统V共享内存。linux发行版本如Redhat 8.0支持mmap()系统调用及系统V共享内存,但还没实现Posix共享内存,本文将主要介绍mmap()系统调用及系统V共享内存API的原理及应用。 一、内核怎样保证各个进程寻址到同一个共享内存区域的内存页面 1、page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述。struct page中有一个域为指针mapping ,它指向一个struct address

进程之间的通信

南笙酒味 提交于 2019-12-16 00:07:03
进程通信 今天的这篇文章,讲给大家详细着讲解他们是如何通信的,让大家尽量能够理解他们之间的区别、优缺点等 1、管道 我们来看一条 Linux 的语句 netstat -tulnp | grep 8080 学过 Linux 命名的估计都懂这条语句的含义,其中”|“是管道的意思,它的作用就是把前一条命令的输出作为后一条命令的输入。在这里就是把 netstat -tulnp 的输出结果作为 grep 8080 这条命令的输入。如果两个进程要进行通信的话,就可以用这种管道来进行通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信方式称之为匿名管道。 并且这种通信方式是单向的,只能把第一个命令的输出作为第二个命令的输入,如果进程之间想要互相通信的话,那么需要创建两个管道。 居然有匿名管道,那也意味着有命名管道,下面我们来创建一个命名管道。 mkfifo test 这条命令创建了一个名字为 test 的命名管道。 接下来我们用一个进程向这个管道里面写数据,然后有另外一个进程把里面的数据读出来。 echo "this is a pipe" > test // 写数据 这个时候管道的内容没有被读出的话,那么这个命令就会一直停在这里,只有当另外一个进程把 test 里面的内容读出来的时候这条命令才会结束。接下来我们用另外一个进程来读取 cat < test // 读数据 我们可以看到

RuntimeError: DataLoader worker (pid XXX) is killed by signal: Bus error 两种解决方案

自古美人都是妖i 提交于 2019-12-15 05:06:23
RuntimeError: DataLoader worker (pid XXX) is killed by signal: Bus error 两种解决方案 第一种 ,权宜之计 把 代码中的 dataloader 改掉 num-worker改低 不行就 = 1 试试 第二种,docker的问题,docker分配的共享内存太少了 查了上述错误原因:df -h查看,共享内存不足: docker内查到的/dev/shm共享内存 真机的共享内存 网上说的办法1,是docker run的时候加参数--shm-size,拿起不得重装?? 现有container能否改这个size呢?查看这个 https://blog.csdn.net/shmily_lsl/article/details/81166951 找到容器对应的配置文件hostconfig.json,找到参数"ShmSize",改!重启doker!!! 搞定: 参考: 链接:https://www.jianshu.com/p/4398bdb9e2d2 https://blog.csdn.net/shmily_lsl/article/details/81166951 来源: CSDN 作者: Longlongaaago 链接: https://blog.csdn.net/Willen_/article/details/103489485

11、UC IPC进程间通信

自作多情 提交于 2019-12-15 00:59:04
耦合性 代码的耦合性越低越好 内聚性 内聚性越强越好 一、IPC进程间通讯 system v IPC 使用命令ipcs可以查看system v IPC的对象 第一步:获取一个键值(唯一的值) 如果获取一个键值? 使用ftok(3)获取一个键值 # include <sys/types.h> # include <sys/ipc.h> key_t ftok ( const char * pathname , int proj_id ) ; 功能:转换pathname和proj_id为一个key值 参数: pathname:指定文件的名字 proj_id:一个整数,这个整数的低 8 位不能为 0 返回值: - 1 错误 errno被设置 成功 key值被返回 举例验证,使用ftok(3)获取一个键值 代码参见 ftok.c 如果文件名字和数字完全一样,多次运行进程产生的key值,完全一样。 第二步:通过键值获取一块内存,将这块内存id返回 第三步:通过内存的id操作这块内存 包含以下三个方面: 1、消息队列 通过键值获取一块内存,将这块内存id返回。 需要使用到msgget(2)获取内核内存的id # include <sys/types.h> # include <sys/ipc.h> # include <sys/msg.h> int msgget ( key_t key ,

进程之间究竟有哪些通信方式?如何通信?

旧街凉风 提交于 2019-12-14 01:49:35
进程之间究竟有哪些通信方式?如何通信? 1、管道 我们来看一条 Linux 的语句 1 | netstat - tulnp | grep 8080 学过 Linux 命名的估计都懂这条语句的含义,其中”|“是管道的意思,它的作用就是把前一条命令的输出作为后一条命令的输入。在这里就是把 netstat -tulnp 的输出结果作为 grep 8080 这条命令的输入。如果两个进程要进行通信的话,就可以用这种管道来进行通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信方式称之为匿名管道。 并且这种通信方式是单向的,只能把第一个命令的输出作为第二个命令的输入,如果进程之间想要互相通信的话,那么需要创建两个管道。 居然有匿名管道,那也意味着有命名管道,下面我们来创建一个命名管道。 1 | mkfifo test 2 | 这条命令创建了一个名字为 test 的命名管道。 接下来我们用一个进程向这个管道里面写数据,然后有另外一个进程把里面的数据读出来。 1 | echo "this is a pipe" > test / / 写数据 这个时候管道的内容没有被读出的话,那么这个命令就会一直停在这里,只有当另外一个进程把 test 里面的内容读出来的时候这条命令才会结束。接下来我们用另外一个进程来读取 1 | cat < test / / 读数据 我们可以看到,test

【Linux】malloc 与共享内存原理区别

戏子无情 提交于 2019-12-14 01:15:06
本文主要分析内存以及I/O相关的系统调用和库函数的实现原理,根据原理给出在使用过程中需要注意的问题和优化的侧重点,本文涉及到的系统调用包括readahead,pread/pwrite,read/write,mmap,readv/writev,sendfile,fsync/fdatasync/msync,shmget,malloc。 本文先简单介绍应用程序对内存的使用以及I/O系统对内存的使用的基本原理,这对理解上述系统调用和库函数的实现有很大帮助。 1 内存管理基础 Linux对物理内存的管理是以页为单位的,通常页大小为4KB,Linux在初始化时为所有物理内存也分配了管理数据结构,管理所有物理页面。 每一个应用程序有独立的地址空间,当然这个地址是虚拟的,通过应用程序的页表可以把虚拟地址转化为实际的物理地址进行操作,虽然系统可以实现从虚拟地址到物理地址的转换,但并非应用程序的每一块虚拟内存都对应一块物理内存。Linux使用一种按需分配的策略为应用程序分配物理内存,这种按需分配是使用缺页异常实现的。比如一个应用程序动态分配了10MB的内存,这些内存在分配时只是在应用程序的虚拟内存区域管理结构中表示这一区间的地址已经被占用,内核此时并没有为之分配物理内存,而是在应用程序使用(读写)该内存区时,发现该内存地址对应得物理内存并不存在,此时产生缺页异常

进程间通信的方式——信号、管道、消息队列、共享内存

自闭症网瘾萝莉.ら 提交于 2019-12-12 03:22:59
常见的通信方式: 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。 来源: CSDN 作者: 行乔_cshuang 链接: https://blog

开发板上面查看共享内存情况

谁说胖子不能爱 提交于 2019-12-11 12:43:20
1.共享内存查看 使用ipcs命令,不加如何参数时,会把共享内存、信号量、消息队列的信息都打印出来,如果只想显示共享内存信息,使用如下命令: ipcs -m 2.共享内存修改大小 cat /proc/sys/kernel/shmmax 临时修改:在root用户下执行# echo 268435456 > /proc/sys/kernel/shmmax把共享内存大小设置为256MB; 永久修改:在root用户下修改/etc/rc.d/rc.local文件,加入下面一行: echo 268435456 > /proc/sys/kernel/shmmax 来源: https://www.cnblogs.com/zhuangquan/p/12021064.html

perl IPC::Shareable 共享内存

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-10 14:13:30
server.pl #!/usr/bin/perl use strict; use IPC::Shareable; my $key = 'data'; my %options = ( create => 1, exclusive => 1, mode => 0644, destroy => 1, ); my %colors; tie %colors, 'IPC::Shareable', $key, { %options } or die "Server: tied failed"; %colors = ( red => [ 'fire truck', 'leaves in the fall', ], blue => [ 'sky', 'police cars', ], ); ((print "Server: there are 2 colors\n"), sleep 2) while scalar keys %colors == 2; print "Server: here are all my colors:\n"; foreach my $c (keys %colors){ print "Server: these are $c: ", join(', ', @{$colors{$c}}), "\n"; } exit; client.pl #!/usr/bin/perl -w

19、共享内存mmap

不问归期 提交于 2019-12-10 05:33:12
1、特点: ① 进程相关的 ② 与 XSI 共享内存一样,需要与同步原语一起使用 ③ 只能是有共同祖先的进程才能使用 2、使用 系统调用 mmap() 用于共享内存的两种方式: ( 1 )使用普通文件提供的内存映射: 适用于任何进程之间。此时,需要打开或创建一个文件,然后再调用 mmap() 典型调用代码如下: fd=open(name, flag, mode); if(fd<0) ... ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0); 通过 mmap() 实现共享内存的通信方式有许多特点和要注意的地方,可以参看 UNIX 网络编程第二卷。【 3 】 ( 2 )使用特殊文件提供匿名内存映射: 适用于具有亲缘关系的进程之间。由于父子进程特殊的亲缘关系,在父进程中先调用 mmap() ,然后调用 fork() 。那么在调用 fork() 之后,子进程继承父进程匿名映射后的地址空间,同样也继承 mmap() 返回的地址,这样,父子进程就可以通过映射区域进行通信了。一般来说,子进程单独维护从父进程继承下来的一些变量。而 mmap() 返回的地址,却由父子进程共同维护。 对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式 。此时,不必指定具体的文件,只要设置相应的标志即可。 3、说明 (1