为什么微信接收的图片在哪里图片是一张一张的

帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:1&分页:真地青发信人: dp2 (卡列宁的微笑), 信区: CPlusPlus
标&&题: [合集] boost 编译慢的问题大家怎么解决的?
发信站: 水木社区 (Fri Jan 11 10:41:19 2013), 站内 && ☆─────────────────────────────────────☆ &&
grapepi (葡萄皮) 于
(Thu Apr&&5 10:53:55 2012)
提到: && VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)…… && 大家有什么提高编译速度的对策?或者还是忍着? && 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小? && btw, 我是为了用 boost 中的 memory mapped file 功能 &&&&&& ☆─────────────────────────────────────☆ &&
alextooter (天津桥上无人识,闲倚栏杆看落晖) 于
(Thu Apr&&5 11:20:19 2012)
提到: && incredibuild&& 【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
ziqin (子青|会挽雕弓如满月|西北望|射天狼) 于
(Thu Apr&&5 11:47:49 2012)
提到: && put into pre-compile header && 【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略
感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随
着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
nalch (nalch) 于
(Thu Apr&&5 13:08:58 2012)
提到: && 尽可能减少include boost的cpp文件数量。
如果有必要,把boost头文件扔预编译头文件里面 && 和源文件大小基本关系不大,解析模板是最费时间的,远高于我们写的cpp文件所需时间
【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
nalch (nalch) 于
(Thu Apr&&5 13:12:38 2012)
提到: && 使用boost编译慢了是一个问题,还有一点不能忍的是svn操作,数量众多的小文件,在机械硬盘上点一次乌龟svn commit,基本就得1分钟开外才能有响应
【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
RoachCock (拜康神教教主) 于
(Thu Apr&&5 13:21:57 2012)
提到: && boost 基本把什么玩意都搞成模板,在缺少真正的 module 机制的 C++ 语言里就必然
会导致这样的悲剧。 && 【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
Tux (蓝色幽灵) 于
(Thu Apr&&5 13:36:45 2012)
提到: && 少用... && 有段时间我用了CGAL, boost等一堆模版库, 编译奇慢... && 【 在 grapepi (葡萄皮) 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
flyp (大奶糖白兔) 于
(Thu Apr&&5 14:40:19 2012)
提到: && 编译CGAL太可怕了。
【 在 Tux (蓝色幽灵) 的大作中提到: 】
: 有段时间我用了CGAL, boost等一堆模版库, 编译奇慢...
&&&&&& ☆─────────────────────────────────────☆ &&
grapepi (葡萄皮) 于
(Thu Apr&&5 19:02:44 2012)
提到: && C++什么时候能引入模块呀,那样就可以放心大胆地用了! && 【 在 RoachCock (拜康神教教主) 的大作中提到: 】
: boost 基本把什么玩意都搞成模板,在缺少真正的 module 机制的 C++ 语言里就必然
: 会导致这样的悲剧。
&&&&&&&& ☆─────────────────────────────────────☆ &&
PGP (---) 于
(Thu Apr&&5 19:33:36 2012)
提到: && 保守估计要到c++30 && 【 在 grapepi (葡萄皮) 的大作中提到: 】
: C++什么时候能引入模块呀,那样就可以放心大胆地用了!
&&&&&&&& ☆─────────────────────────────────────☆ &&
xpay (xpay) 于
(Tue Apr 17 13:03:28 2012)
提到: && boost 就是一帮不愁吃穿的社会闲杂人等在那里华山论剑,看谁剑术最花,而不是最实用 && 【 在 RoachCock (拜康神教教主) 的大作中提到: 】
: boost 基本把什么玩意都搞成模板,在缺少真正的 module 机制的 C++ 语言里就必然
: 会导致这样的悲剧。
&&&&&& ☆─────────────────────────────────────☆ &&
noho (血骑士 碧血残阳) 于
(Wed Apr 18 14:59:53 2012)
提到: && 解决办法是不用。 && 【 在 grapepi 的大作中提到: 】
: VC 下面,编译用到 boost 的 cpp 文件,比类似功能的 c 文件慢 5-10 倍(粗略感觉)……
: 大家有什么提高编译速度的对策?或者还是忍着?
: 另外各位有没有什么经验,关于这个编译速度的差距与源文件大小是线性关系,还是随着源文件变大而差距变小?
: ...................
&&&&&& ☆─────────────────────────────────────☆ &&
leslin (我心有约) 于
(Wed Apr 18 18:27:58 2012)
提到: &&&& 【 在 xpay 的大作中提到: 】
: boost 就是一帮不愁吃穿的社会闲杂人等在那里华山论剑,看谁剑术最花,而不是最实用
:&& && 倒也不是不能用。就像武功里高级招式都需要辅以内功才能发挥威力,boost也类似。相应的内功心法包括: && CPU要强,硬盘要快,码农耐心要好
。。。 && 诸如此类的 &&&& ☆─────────────────────────────────────☆ &&
flybb (倒影) 于
(Wed Apr 18 19:45:08 2012)
提到: && cmake生成vc项目 && window上编译暴快 && 【 在 flyp (大奶糖白兔) 的大作中提到: 】
: 编译CGAL太可怕了。
&&&&&&&& 文章数:1&分页:Linux平台Boost的编译方法_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Linux平台Boost的编译方法
来源:csdn&
作者:阿波ID:livelylittlefish
Linux平台Boost的编译方法
Boost的编译使用的不是已经成为公认标准的make,而是专门为Boost开发的工具bjam(boost jam)。
本文以boost1.40为例,在Linux平台的编程环境为gcc4.4.1,假设Boost代码在/usr/src/boost_1_40_0目录,步骤如下。
1. 获得bjam
获得bjam有3种方式,如下:
方法1:Boost网站上提供了各种平台上预编译好的bjam可执行程序,可直接下载使用。
方法2:从Boost源代码中提供的bjam代码编译出可执行程序。
方法3:通过bootstrap程序生成bjam。
# apt-get install bjam
(1) # cd /usr/src/boost_1_40_0/tools/jam/src
(2) # ./build.sh
编译完成后:
&&& 生成的可执行文件为
&&& # /usr/src/boost_1_40_0/tools/jam/src/bin.linuxx86/bjam&&& 需要将bjam.exe拷贝到源代码所在的目录&&& # cp bin.linuxx86/bjam& /usr/src/boost_1_40_0
(1) # cd /usr/src/boost_1_40_0
(2) # ./bootstrap.sh
该方法直接在Boost源代码目录下生成bjam文件。
2. 修改bjam配置
使用bjam前,需要修改bjam的配置文件。Linux平台的配置文件:
/usr/src/boost_1_40_0/tools/build/v2/user-config.jam
修改如下。注:笔者在实验时,不修改貌似也很正常。
将43行的“# using gcc ;”前的注释符号‘#’去掉,表明用到使用gcc编译。
如果要使用STLport作为其标准库,将75行前的‘#’去掉。
3. 完整编译Boost
对Boost进行完整编译,生成所有调试版、发行版的静态库和动态库。
# cd /usr/src
# wget http://sourceforge.net/projects/boost/files/boost/1.40.0/boost_1_40_0.tar.bz2
# tar --bzip2 -xvf boost_1_40_0.tar.bz2
# cd boost_1_40_0
# bjam --toolset=gcc --build-type=complete stage
# ./bjam --build-type=complete --layout=versioned
# cd /usr/src/boost_1_40_0/tools/jam
# ./build_dist.sh
也会完成Linux平台bjam和Boost的所有编译工作,并生成所有调试版、发行版的静态库和动态库。但不推荐该方式。
编译成功后,将在/usr/src/boost_1_40_0/bin.v2目录下生成诸多文件,包括.a和.so.1.40.0文件,这就是在Linux平台要使用Boost需要的,其他的文件可以删除。
# ./bjam install
将生成的库默认安装到/urs/local/lib目录。
4 部分编译Boost
完整编译Boost费时费力,且这些库在开发过程中并不一定全部用到,因此,bjam也支持用户自行选择要编译的库。
在完全编译的基础上,使用--with或者—without选择可以打开或者关闭某个库的编译,例如,仅仅编译date_time库:
# cd /usr/src/boost_1_40_0
# ./bjam --toolset=msvc --with-date_time --build-type=complete stage
当然,bjam还有很多其他选项,如指定安装路径,指定debug或release等,可参考bjam文档或帮助。
相关资讯 & & &
& (06月15日)
& (01月08日)
& (01月08日)
& (01月08日)
& (01月08日)
& (08/18/:11)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
老杨 发表于 不行呀,还是装不上你正在使用的浏览器版本过低,将不能正常浏览和使用知乎。[翻译,boost]共享内存_3_内存映射文件
时间: 02:20:33
&&&& 阅读:748
&&&& 评论:
&&&& 收藏:
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&Memory Mapped Files
内存映像文件
What is a memory mapped file ?
什么是内存映像文件 ?
File mapping is the association of a file‘s contents with a portion of the address space of a process.
文件映像就是建立文件中所包含的内容与进程内存地址中的部分空间二者之间的联系
The system creates a file mapping to associate the file and the address space of the process.
系统创建文件映像的目的就是为了通过它建立文件与进程地址空间的联系
A mapped regsion is the portion of address that the process uses to access the file‘s contents .
映射域是(进程)地址的一部分,通过映射域可以在进程中访问(映像)文件中的内容
A single file mapping can have several mapped regsions,so that the user can associate parts of the file with the address space of the process without
mapping the entire file in the address space, since the file can be bigger than the whold address space of the process ( a 9GB DVD image file in a usual 32 bit systems).
就单个的映像文件而言,它可以被映射到多个映射域中。这样的话,使用者便可以将与之关联的文件段映射到其所在的进程地址空间中,而不是
把整个的映像文件映射到地址空间中,因为映像文件的大小有可能要远比整个进程地址空间要大(进程地址空间的大小 在常见 32 位系统中有一个 9GB 的DVD 视频文件那么大)
Processes read from and write to the file using pointers ,just like with dynamic memory .
同访问动态分配而创建的内存空间的方法一样,进程使用指针向映像文件中读取、写入数据
File mapping has the following advantages:
使用映像文件(来作为共享内存对象)有着如下的优点:
&&&&&&& Uniform resource use. File and memory can be treated using the same functions
&&&&&&& 统一资源使用方式. 文件与内存可以通过相同的方法来访问.
&&&&&&& Automatic file data synchronization and cache from the OS.&&&&
&&&&&&&& 操作系统会为文件提供自发的数据同步策略以及文件缓存机制(这些无需自己编程实现)
& &&&&& Reuse of C++ utilities( STL containers, algorithms) in files.
&&&&&&& 在操作文件对象的时候,可以重用 C++ 中的许多公共库函数(比如 STL 容器库,算法库都可以用在文件对象上)
&&&&&&& Shared memory between two or more applications.
&&&&&&&& (使用映像文件作为共享内存对象的话)可以在两个或更多的应用进程间创建共享内存.
&&&&&&& Allows efficient work with a large files, without mapping the whole file into memory
&&&&&&& 不将全部的文件映射到进程地址空间,这一特点提高将大文件作为共享内存对象的工作效率
&&&&&&& If several processes use the same file mapping to create mapped regions of a file , each process‘ views contain identical copies of the file on disk.
&&&&&&& 如果多个进程将同一个文件映射到自己的进程地址空间并将其映射为映射域对象的话,(是不会将该文件多次存储的)每个进程所看到的全都是同一个来自于硬盘上的该映像文件的唯一的拷贝.
File mapping is not only used for interprocess communication, it can be used also to simplify file usage, so the user does not need to use file-management functions
write to the file.
文件映像不仅能用在进程间通信方面,它还可以被用在简化文件操作方面,这样一来使用者便无需通过使用文件管理方法来向文件中写数据了.
The user just writes data to the process memory, and the operating systems dumps the data to the file. &&&&&&
用户仅可以通过将数据写入到进程内存中,随后操作系统便会将写入的数据转储到文件中.
When two processes map the same file in memory, the memory that one process writes is seen by another process, so memory mapped files can be used as an
interprocess communication mechanism.
当两个进程把同一个文件映射到其内存地址空间中时,其中一个进程向共享内存写入的数据对于另个一进程时可见的,所以创建内存映像文件可以被用作进程间通信
的一种机制
We can say that memory-mapped files offer the same interprocess communication services as shared memory with the addition of filesystem persistence.
我们可以得出这样的结论: 内存映像文件和共享文件一样可被用在进程通信服务中,除此之外,内存映像文件还具备有着与文件系统同样的生命周期, 正是因为这一点,
让写入到映像文件中的数据可被持久化.
However,as the operating system has to synchronize the file contents with the memory contents, memory-mapped files are not as fast as shared memory.
但是,由于操作系统不得不同步化文件与内存中的数据,这使得映像文件内存的读写速度远不及共享内存.
Using mapped files
使用映像文件
To use memory-mapped files, we have to perform 2 basic steps:
使用内存映像文件,我们需要执行下面两步基本的操作:
&&&&&&&&&&& Create a mappable object that represent an already created file of the fillesystem.
&&&&&&&&&&&&&& 创建可被映射的对象用来表示已经创建于文件系统中的文件
&&&&&&& & & This object will be used to create multiple mapped regions of the file.
&&&&&&&&&&&&& 这个可被映射对象将被用作做,被多次映射到(不同进程中的) 由映射文件创建的映射域
&&&&&&&&&&&&&& Associate the whole file or parts of the file with the address space of the calling process.
&&&&&&&&&&&&&& 建立需要映射的进程中的地址空间与整个文件或是部分文件之间的映射关系
&&&&&&&&&&&&&& The operating system looks for a big enough memory address range in the calling process‘ address space and marks that address range as an spacial range.
&&&&&&&&&&&&&& 操作系统会在所有申请映射进程的内存地址中找出一个足够大的出来,然后将该地址区域标志为特殊的内存地址域
&&&&&&&&&&&&& Changes in that address range are automatically seen by other process that also have mapped the same file and those changes are also transferred to the disk
&&&&&&&&&&&&&& automatically.
&&&&&&&&&&&&&& 在特殊地址域中的数值变化对其他将相同文件映射到自己地址域中的进程,是自动可见的,并且对该特殊地址域中数值的修改会被(操作系统)自动的转储到
&&&&&&&&&&&&&& (该映像文件所存放的)硬盘中。
Once the two steps have been successfully completed, the process can start writing to and reading from the address space to send to and receive data from other process
and synchronize the file‘s contents with the changes made to the mapped region.
这两个步骤一经成功执行,进程便可开始从该地址空间中写入发送给其他进程的数据和读出来自于其他进程的数据信息了,同时还可以将映射域中数据的变化同步到
Now,let‘s see how can we do this using Boost.Interprocess.
好的,那么我们来看看如何使用 Boost.Interprocess 函数库来实现上述的情景
需要引入的头文件
To manage mapped files, you just need to include the following header.
想要操作映射文件,你仅需要把下面的头文件引入到自己的代码文件中.
#include &boost/interprocess/file_mapping.hpp&
Creating a file mapping
创建映像文件
First , we have to link a file‘s contents with the process‘ address space.
首先,我们需要做的就是创建文件的内容与进程地址空间二者的链接关系
To do this, we have to create a mappable object that represents that file.
这么做的话,我们就要创建一个用来代表该文件的可映射的对象.
This is achieved in Boost.Interprocess creating a file_mapping object:
上述的这个功能在 Boost.Interprocess 库中已经被实现了,只需要创建一个 file_mapping 的实例对象即可:
using boost::
file_mapping m_file ("/user/home/file " ,& // filename 这个便是所要创建的映像文件的文件名称
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& read_write ,&& &&&&&&&& // read-write mode 这个是映像文件允许被访问的模式
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&) ;
Now we can use the newly create object to create mapped regions.
现在我们就可以使用新创建的对象来生成映射域了
Mapping File‘s Contents In Memory
将文件中的内容映射如内存中
After creating a file mapping, a process just has to map the shared memory in the process‘ address space.
在创建映像文件之后,进程便可以将这个映像文件作为共享内存对象映射到自己的进程地址空间中.
The user can map the whole shared memory or just part of it.
使用者(进程) 可以把整个或是其中的一部分文件映射到自己的进程地址空间中.
The mapping process is done using the mapped_region class , as we have said before .
映射的过程, 如我们之前所说的一样,通过创建mapped_region 类实例便可以实现
The class represents a memory region that has been mapped from a shared memory or from other devices that have also mapping capabilities:
mapped_region 这个类(抽象)表示的是: 从一个共享内存或是其他具有可映射性的设备中提取出来的一块内存区域
using boost::
std::size_t FileSize = ...
// Map the second half of the file
mapped_region region
&&&& m_file , &&&&&&&&&&&&&&&&&&&&&&&&// Memory-mappable object&& 内存-可映射 对象
&&&& read_write , &&&&&&&&&&&&&&&&& // Access mode&&&&&&&&&&&&&&&&&&& 访问内存映射对象的模式
&&&& FileSize / 2 , &&&&&&&&&&&&&&&&// Offset from the beginning of the shm&&&&&&&&&&&&&&&&&& 从内存-可映射对象起始位置多少字节开始映射
&&&& FileSize - FileSize/2& , &&&&// length of the region &&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 从内存-可映射 中映射多少个自己额
// Get the address of the region
// 该方法 get_address () 来自于 mapped_region 类,用来获取映射域中的起始地址&
region.get_address () ;
// get the size of the region
// get_size()& 方法来自于 mapped_region 类,用于获取映射域所对应的映射对象的字节个数
// 对应于 mapped_region 类构造方法中的第四个参数
region.get_size() ;
The user can specify the offset from the file where the mapped region should start and the size of the mapped region .
使用者可以通过设置 offset 和 size 参数来指定将映像文件从哪里开始映射到映射域中以及将映像文件从起始位置开始向映射域中总共映射多少个字节.
If no offset or size is specified , the whole file is mapped.
如果使用者没有指定 offset 和 size 的数值,默认操作便是将整个文件全部映射到映射域中
If the offset is specified,but not the size, the mapped region covers from the offset until the end of the file.
如果仅指定了 offset (起始位置) 但是没有指定 size(总共设定多少个字节), 映射域将从设定映像文件的 起始位置开始将后续直到文件结束的所有字节
全部映射到映射域中.
If several processes map the same file, and a process modifies a memory range from a mapped region that is also mapped by other process, the changes are
immediately visible to other processes.
如果有多个进程将同样的文件映射到自己的地址空间中,其中一个进程通过映射域修改了内存中的内容,这段被修改的内存同样也会被映射到其他的进程中,
改动的部分对剩余的进程是立即可见的.(这种变动是实时可见的,不存在刷新或是延迟时间)
However, the file contents on disk are not updated immediately, since that would hurt performance ( writing to disk is several times slower than writing to memory).
然而,内存中文件内容的变动是不会立即更新到存放该文件的硬盘上的,因为立即刷新存放在硬盘文件数据的话会影响到程序的性能(刷新硬盘要比刷新内存多花几倍的时间)
If the user wants to make sure that file‘s contents have been updated,it can flush a range from the view to disk.
如果使用者像确保文件内容的更新已经及时写入到该文件存放的硬盘上,它可以通过调用 flush 方法来将内存中某一区域上的数据,来将位于这一区间上的数据更新到磁盘上
// Flush the whole region
// 将整个映射域中变动的数据,刷新到硬盘中
region.flush() ;
// Flush from an offset until the end of the region
// 从 offset 标定的字段开始直到 映射域结束 这一区间上的数据的变动 刷新到硬盘中
region.flush(offset) ;
// Flush a memory range starting on an offset
// 通过指定起始点和字节长度,来将这一区域上变动刷新到硬盘上
// 变化域是 [offset, offset+size)
region.flush( offset, size);
Remember that the offset is not an offset on the file , but an offset in the mapped region.
需要谨记的是,flush 参数中的 offset 数值指的并不是 映像文件中的起始地址 而是 映射域 中的起始地址
If a region covers the second half of a file and flushes the whole region, only the half of the file is guaranteed to have been flushed.
如果映射域中包含的是半个映射文件,那么执行映射域的整体刷新操作的话,仅仅会使得硬盘上的映像文件一半内容得到刷新。
For more details regarding mapped_region see the class reference.
想要知道 mapped_region 更多的细节信息的话,参看 类参考资料
A Simple Example&
Let‘s reproduce the same example described in the shared memory section ,& using memory mapped files.
让我们通过使用内存映像文件来再次重新描述一下在 共享内存哪一张节中所实现的例子吧
A server process creates a shared memory segment, maps it and initializes all the bytes to a value .
服务进程创建了一个共享内存段,并将其映射到映射域中,并通过映射域对象将内存段中的所有字节全部初始化成某一个数值
After that , a client process opens the shared memory, maps it , and checks that the data is correctly initialized :
在此之后,客户进程打开共享内存,将其映射到自己进程的地址空间中,并检查共享内存段中的每个字节是否被正确的初始化.
#include &boost/interprocess/file_mapping.hpp&
#include &boost/interprocess/mapped_region.hpp&
#include &iostream&
#include &fstream&
#include &string&
#include &vector&
#include &cstring&
#include &cstddef&
#include &cstdlib&
int main(int argc, char *argv[])
&&&using namespace boost::interprocess;
&&&//Define file names
& // 首先设定文件名称,创建文件对象作为生成映射域
& // 的共享内存对象
&&&const char *FileName = "file.bin";
&&&const std::size_t FileSize = 10000;
&&&if(argc == 1){ //Parent process executes this
&&&&&&{ //Create a file
&&& &&& // 下面的 if 分支下面的代码是 server 进程将要执行的
&&&&&& // 为了防止在 server 进程之前就有其他进程使用同名的文件作为共享对象创建 映射域
&&&&&& // 造成此次创建映射域的错误,首先删除同名文件所创建的映射域
& && &&& file_mapping::remove(FileName);
//&&&&&&& 随后创建 filebuf 文件缓冲对象,并通过文件缓冲类中的 open 方法将文件以
// 读模式写模式,如果不能存在则创建同名文件和二进制文件模式 打开
&&&&&&&& std::filebuf fbuf;
&&&&&&&&&fbuf.open(FileName, std::ios_base::in | std::ios_base::out
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&| std::ios_base::trunc | std::ios_base::binary);
&&&&&&&&&//Set the size
&&&&&&&& // 将文件位移指针 以文件的起始位置开始移动指向文件中最后一个字节上
&&&&&&&&&fbuf.pubseekoff(FileSize-1, std::ios_base::beg);
&&&&&&& // 将文件中最后一个字节的数据置为数值 0
&&&&&&&&&fbuf.sputc(0);
&&&&&&//Remove on exit
&&&& // 创建封装了 移除映像文件操作的 结构体
&&& // 结构体的构造函数 用于为结构体中的 FileName_ 变量进行赋值操作
&& // 而结构体的析构函数 用于将指定名称的文件对应的共享内存移除
&&&&&&struct file_remove
&&&&&&&&&file_remove(const char *FileName)
&&&&&&&&&&&&: FileName_(FileName) {}
&&&&&&&&&~file_remove(){ file_mapping::remove(FileName_); }
&&&&&&&&&const char *FileName_;
&&&&&&} remover(FileName);
&&&&&&//Create a file mapping
&&&&& // 基于刚刚创建的映像文件进行映射, m_file 便是基于该映像文件生成的共享内存对象
&&&&&&file_mapping m_file(FileName, read_write);
&&&&&&//Map the whole file with read-write permissions in this process
&&& // 在本进程中将全部的共享内存对象映射到映射域中
&&&&&&mapped_region region(m_file, read_write);
&&&&&&//Get the address of the mapped region
&&&& // 通过生成的映射域对象,可以获取该共享内存的起始地址 和 该共享内存的大小(字节)
&&&&&&void * addr = region.get_address();
&&&&&&std::size_t size = region.get_size();
&&&&&&//Write all the memory to 1
&&&&& // 将共享内存中的所有字节均置为数值 1
&&&&&&std::memset(addr, 1, size);
&&&&&&//Launch child process
&&&& // 接下来运行子进程,将运行命令从之前的 ./demo ---& 修改为 ./demo child
&&&& // argc 从 1 ---& 2 导致 if(argc != 1 ) 从而走的是 else 分支
&&&&&&std::string s(argv[0]); s += " child ";
&&&&&&if(0 != std::system(s.c_str()))
&&&&&&&&&return 1;
&&&else{ //Child process executes this
&&&&&&{ //Open the file mapping and map it as read-only
&&&&&&&&//
&&&&&&& // 下面的代码是 子进程 执行的
&&&&&&& // 首先是创建 file_mapping 实例
&&&&&&&& file_mapping m_file(FileName, read_only);
&&&&&& // 紧接着使用 m_file 实例作为共享内存实体 映射生成映射域 对象
&&&&&&&& mapped_region region(m_file, read_only);
&&&&&&&&&//Get the address of the mapped region
&&&&&&&& // 有了映射域便可以方便的对共享内存施加操作
&&&&&&& // 通过 get_address () 方法来获取共享内存中的起始地址,通过 get_size() 来获取共享空间的大小(字节)
&&&&&&&&&void * addr = region.get_address();
&&&&&&&&&std::size_t size = region.get_size();
&&&&&&&&&//Check that memory was initialized to 1
&&&&&&&&&const char *mem = static_cast&char*&(addr);
&&&&&&&&&for(std::size_t i = 0; i & size; ++i)
&&&&&&&&&&&&if(*mem++ != 1)
&&&&&&&&&&&&&&&return 1; //Error checking memory
&&&&&&{ //Now test it reading the file
&&&&&&& // 下面的这个分支是前面几个示例代码中所不包含的,这个是因为共享内存创建所基于的实体是文件
&&&&&&& // 而文件是可以被持久化存放到磁盘上面的,所以涉及到读入到内存中的文件在被修改之后,如何,何时才会将内存中的改变刷新到硬盘上这些问题
// 而下面的这些代码便是验证,上述操作之后,作为共享内存实体的映像文件所存放的文件中的内容是否发生了改变
//&&&&&&& 首先将硬盘上存放的文件读入到当前(子进程) 的内存中
&&&&&&&&&std::filebuf fbuf;
&&&&&&&&&fbuf.open(FileName, std::ios_base::in | std::ios_base::binary);
&&&&&&&&&//Read it to memory
&&&&&&& // 然后,创建一个用来缓冲文件中的数据,容纳字节个数=文件长度 的char 类型的 vector 对象
&&&&&&&&&std::vector&char& vect(FileSize, 0);
// 随之调用 filebuf 中的 sgetn 方法将文件中的内容依次读入到 vector&char& 中, 话说这里的 sgetn , streamsize 我还是从来没有用过
&&&&&&&&&fbuf.sgetn(&vect[0], std::streamsize(vect.size()));
&&&&&&&&&//Check that memory was initialized to 1
&&&&&&& //
&&&&&&& // 接下来的操作也是遍历 vecto&char& 中的所有元素看看是否是每个字节的数值与 共享空间在 server 进程初始化的数值一样都是数值 1
&&&&&&&&&const char *mem = static_cast&char*&(&vect[0]);
&&&&&&&&&for(std::size_t i = 0; i & FileSize; ++i)
&&&&&&&&&&&&if(*mem++ != 1)
&&&&&&&&&&&&&&&return 1; //Error checking memory
&&&return 0;
to be continued标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://blog.chinaunix.net/uid--id-5073449.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!

我要回帖

更多关于 微信接收图片不显示 的文章

 

随机推荐