1. 程式人生 > >c#實現記憶體對映檔案共享記憶體

c#實現記憶體對映檔案共享記憶體

記憶體對映檔案是利用虛擬記憶體把檔案對映到程序的地址空間中去,在此之後程序操作檔案,就像操作程序空間裡的地址一樣了,比如使用c語言的 memcpy等記憶體操作的函式。這種方法能夠很好的應用在需要頻繁處理一個檔案或者是一個大檔案的場合,這種方式處理IO效率比普通IO效率要高

共享記憶體是記憶體對映檔案的一種特殊情況,記憶體對映的是一塊記憶體,而非磁碟上的檔案。共享記憶體的主語是程序(Process),作業系統預設會給每一 個程序分配一個記憶體空間,每一個程序只允許訪問作業系統分配給它的哪一段記憶體,而不能訪問其他程序的。而有時候需要在不同程序之間訪問同一段記憶體,怎麼辦 呢?作業系統給出了建立訪問共享記憶體的API,需要共享記憶體的程序可以通過這一組定義好的API來訪問多個程序之間共有的記憶體,各個程序訪問這一段記憶體就 像訪問一個硬碟上的檔案一樣。而.Net 4.0中引入了System.IO. MemoryMappedFiles名稱空間,這個名稱空間的類對windows 共享記憶體相關API做了封裝,使.Net程式設計師可以更方便的使用記憶體對映檔案。

在C#中使用共享記憶體。以下App1的程式碼讓使用者輸入一行文字到共享記憶體中;App2不停的重新整理控制檯,輸出最新的共享記憶體內容;App3實現的功能和App2相同,但讀取方法不同。

App1程式碼:
using System;
using System.Collections.Generic;android從資原始檔中讀取檔案流顯示
using System.Linq;
using System.Text;

using System.IO;

//引用記憶體對映檔案名稱空間
using System.IO.MemoryMappedFiles;

namespace App1
{
    class Program
    {
        static void Main(string[] args)
        {
            long capacity = 1<<10<<10;

            //建立或者開啟共享記憶體
            using (var mmf = MemoryMappedFile.CreateOrOpen("testMmf", capacity, MemoryMappedFileAccess.ReadWrite))
            {
                //通過MemoryMappedFile的CreateViewAccssor方法獲得共享記憶體的訪問器
                var viewAccessor = mmf.CreateViewAccessor(0, capacity);
                //迴圈寫入,使在這個程序中可以向共享記憶體中寫入不同的字串值
                while (true)
                {
                    Console.WriteLine("請輸入一行要寫入共享記憶體的文字:");

                    string input = Console.ReadLine();

                    //向共享記憶體開始位置寫入字串的長度
                    viewAccessor.Write(0, input.Length);

                    //向共享記憶體4位置寫入字元
                    viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
                }

            }
            
        }
    }
}
App2程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

//引用使用記憶體對映檔案需要的名稱空間
using System.IO.MemoryMappedFiles;

namespace App2
{
    class Program
    {
        static void Main(string[] args)
        {
              long capacity = 1<<10<<10;

              using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))
              {
                  MemoryMappedViewAccessor viewAccessor = mmf.CreateViewAccessor(0, capacity);

                  //迴圈重新整理共享記憶體字串的值
                  while (true)
                  {
                      //讀取字元長度
                      int strLength = viewAccessor.ReadInt32(0);                      
                      char[] charsInMMf = new char[strLength];
                      //讀取字元
                      viewAccessor.ReadArray<char>(4, charsInMMf, 0, strLength);
                      Console.Clear();
                      Console.Write(charsInMMf);
                      Console.Write("\r");
                      Thread.Sleep(200);
                  }
              }
        }
    }
}

App3程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO.MemoryMappedFiles;
using System.IO;

namespace App3
{
    class Program
    {
        static void Main(string[] args)
        {
            long capacity = 1 << 10 << 10;
            //開啟共享記憶體
            using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))
            {
                //使用CreateViewStream方法返回stream例項
                using (var mmViewStream = mmf.CreateViewStream(0, capacity))
                {
                    //這裡要制定Unicode編碼否則會出問題
                    using (BinaryReader rdr = new BinaryReader(mmViewStream,Encoding.Unicode))
                    {
                        while (true)
                        {
                            mmViewStream.Seek(0, SeekOrigin.Begin);

                            int length = rdr.ReadInt32();

                            char[] chars = rdr.ReadChars(length);

                            Console.Write(chars);
                            Console.Write("\r");

                            System.Threading.Thread.Sleep(200);
                            Console.Clear();
                        }
                    }
                }
            }
        }
    }
}
在讀資料時用了2種方法。

因為在之前很少會用到程序之間的通訊,所以此方法只是想初步的認識下。此程式寫的過於簡陋,有很多東西都沒有去判斷。比如說是怎麼建立了一個共享記憶體怎麼取刪除它等等。。。

希望我與此篇博文的作者共勉吧。



相關推薦

c#實現記憶體對映檔案共享記憶體

記憶體對映檔案是利用虛擬記憶體把檔案對映到程序的地址空間中去,在此之後程序操作檔案,就像操作程序空間裡的地址一樣了,比如使用c語言的 memcpy等記憶體操作的函式。這種方法能夠很好的應用在需要頻繁處理一個檔案或者是一個大檔案的場合,這種方式處理IO效率比普通IO效率要高

ython實現程序間的通訊有Queue,Pipe,Value+Array等,其中Queue實現多個程序間的通訊,而Pipe實現兩個程序間通訊,而Value+Array使用得是共享記憶體對映檔案的方式,所以速度比較快

1.Queue的使用 from multiprocessing import Queue,Process import os,time,random #新增資料函式 def proc_write(queue,urls): print("程序(%s)正在寫入..."%(os.getpid()))

c++實現使用記憶體對映檔案處理大檔案

摘要:本文給出了一種方便實用的解決大檔案的讀取、儲存等處理的方法,並結合相關程式程式碼對具體的實現過程進行了介紹。引言  檔案操作是應用程式最為基本的功能之一,Win32 API和MFC均提供有支援檔案處理的函式和類,常用的有Win32 API的CreateFile()、W

C# .Net 多程序同步 通訊 共享記憶體 記憶體對映檔案

節點通訊存在兩種模型:共享記憶體(Shared memory)和訊息傳遞(Messages passing)。         記憶體對映檔案對於託管世界的開發人員來說似乎很陌生,但它確實已經是很遠古的技術了,而且在作業系統中地位相當。實際上,任何想要共享資料的通訊模型都會在幕後使用它。         記

c# 記憶體共享記憶體對映檔案

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.IO; using System.Dat

C# .Net 多程序同步 通訊 共享記憶體 記憶體對映檔案 Memory Mapped

節點通訊存在兩種模型:共享記憶體(Shared memory)和訊息傳遞(Messages passing)。         記憶體對映檔案對於託管世界的開發人員來說似乎很陌生,但它確實已經是很遠古的技術了,而且在作業系統中地位相當。實際上,任何想要共享資料的通訊模型都

C/C++(5)實現大資料檔案記憶體對映機制

摘要 本文主要講述大量資料的檔案的記憶體對映機制的實現。 1. 記憶體對映 記憶體對映檔案,是由一個檔案到一塊記憶體的對映。Win32提供了允許應用程式把檔案對映到一個程序的函式 (CreateFileMapping)。記憶體對映檔案與虛擬記憶體有些類似,通過記憶體對映檔

C#記憶體對映檔案訊息佇列實戰演練(MMF—MQ)

一、課程介紹 本次分享課程屬於《C#高階程式設計實戰技能開發寶典課程系列》中的一部分,阿笨後續會計劃將實際專案中的一些比較實用的關於C#高階程式設計的技巧分享出來給大家進行學習,不斷的收集、整理和完善此係列課程! 訊息佇列這個概念名稱相比大家都不陌生!今天阿笨這裡說的MQ並不是記憶體佇列(Queu

[翻譯,boost]共享記憶體_3_記憶體對映檔案

What is a memory mapped file ? 什麼是記憶體映像檔案 ?File mapping is the association of a file's contents with a portion of the address space of

作業系統-記憶體對映檔案

(臨時筆記 後面再修改) 將檔案對映到一個正在執行的程序的地址空間。 例如,假設一個檔案f,長度為64,對映到從512k地址開始的虛地址出,這樣任何機器指令在512地址處讀取位元組內容會得到檔案的第0個位元組,類似的,像512K+21000地址處寫入則修改了檔案的第210

c/c++實現的一個動態分配記憶體的結構體陣列(類似vector)

這個陣列可以向裡面插入任何型別,包括自定義型別, 程式只是實現了基本功能,還有待完善, 首先初始化,然後就可以插入資料了, 當儲存單元不足的時候就自動增加儲存單元 由於總的風格是c, 所以看著很是彆扭, 有空了把全部改成c++風格的; 說有空就有空了,改成了c++風格了,

【java】記憶體對映檔案、虛擬記憶體、RandomAccessFile類

Windows提供了3種進行記憶體管理的方法:  • 虛擬記憶體,最適合用來管理大型物件或結構陣列。  • 記憶體對映檔案,最適合用來管理大型資料流(通常來自檔案)以及在單個計算機上執行的多個程序之間共享資料。  • 記憶體堆疊,最適合用來管理大量的小物件。 1.什麼是

14 記憶體對映檔案

記憶體對映檔案:把一個硬碟上的檔案,直接對映到物理頁上,然後再把物理頁上的記憶體直接對映到虛擬記憶體中;在虛擬記憶體中操作就直接相當於操作檔案; 記憶體對映檔案示例: A程式程式碼如下: /* *MappingFile.h */ #ifndef FILE_SYSTEM_H #defi

對映檔案記憶體,像操作記憶體一樣方便讀寫檔案——MemFile

編碼中操作檔案是常有的事,本文封裝了一種不一樣的讀寫檔案方式,通過對映檔案可以想操作記憶體一樣方便的讀寫檔案。 方法解釋: Attach:關聯已存在的檔案並對映到記憶體,不存在返回NULL; Detach:取消關聯機器對映; Alloc:建立一個新的檔案並對映到記憶體; C

使用記憶體對映檔案來提高你程式的效能

 本人在學習《WINDOWS核心程式設計》的時候對JEFFREY大師提到的一個小程式寫了兩個版本來比較效能,該程式的原始需求是這樣的:對一個大檔案進行倒序,也就是將一個檔案頭變成尾,尾變成頭。   使用的方法有很多種,這裡使用兩個方法來比較,主要是突出使用記憶體對映檔案好處;

C++實現多執行緒物件記憶體池帶垃圾回收機制

#include <Windows.h> #include <iostream> #include <map> #include <string> #include <assert.h> #include <

程序間通訊——記憶體對映/檔案對映形式

記憶體對映/檔案對映形式下的程序交通訊不分32位還是64位,是因為本質上使用的是系統物理頁面(系統位數)。 主要是三個函式:CreateFileMapping;MapViewOfFile(對映記憶體)

Java NIO 檔案IO-記憶體對映檔案MappedByteBuffer與zerocopy

在傳統的檔案IO操作中,我們都是呼叫作業系統提供的底層標準IO系統呼叫函式read()、write() ,此時呼叫此函式的程序(在JAVA中即java程序)由當前的使用者態切換到核心態,然後OS的核心程式碼負責將相應的檔案資料讀取到核心的IO緩衝區,然後再把資料

匯出記憶體映象檔案記憶體異常分析(MAT工具)

記憶體溢位自動匯出引數: //發生溢位時dump出來 -XX:+HeapDumpOnOutOfMemoryError //dump的路徑 ./為專案啟動根路徑 -XX:HeapDumpPath=./ 記憶體溢位手動匯出引數:jmap命令使用 jdk安裝後會自帶一些小工具,jmap

C++實現操作配置檔案(告別跨平臺問題)

CConfig.h #ifndef _CCONFIG_H #define _CCONFIG_H #include <iostream> #include <string> #include <fstream> #include <vector>