Опитвам се да изградя разпределителна изчислителна система, която използва файлове за картографиране на паметта, за да координира работата между няколко компютъра в мрежа, всички чрез VBA. Казано по друг начин, искам да накарам група мрежови компютри да работят едновременно по координиран начин по един проект, който може лесно да бъде разделен на различни части. Един компютър отнема 13+ часа, за да завърши проекта, което не е практично за моя клиент.
Искам да съхранявам информация във файловете за картографиране на паметта, която ще помогне на компютрите да работят по проекта по координиран начин (т.е. без дублиране на работа, избягване на проблеми със състезание и т.н.). Опитах да използвам други типове файлове, за да постигна това и това причинява проблеми с надпреварата на файловете или отнема твърде много време. И така, както беше предложено в този форум, опитвам файлове за картографиране на паметта.
Съвсем нов съм в файловете за картографиране на паметта и разпределителните изчисления. Трябва да се направи във VBA. Доколкото знам, трябва да уточня, че файлът се запазва в директория в нашата мрежа (устройство Z тук), до която всички компютри имат достъп. Събрах код от различни места:
Option Explicit
Private Const PAGE_READWRITE As Long = &H4
Private Const FILE_MAP_WRITE As Long = &H2
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_ALWAYS = 4
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CreateFileMapping Lib "kernel32.dll" Alias "CreateFileMappingA" ( _
ByVal hFile As Long, _
ByVal lpFileMappigAttributes As Long, _
ByVal flProtect As Long, _
ByVal dwMaximumSizeHigh As Long, _
ByVal dwMaximumSizeLow As Long, _
ByVal lpName As String) As Long
Private Declare Function MapViewOfFile Lib "kernel32.dll" ( _
ByVal hFileMappingObject As Long, _
ByVal dwDesiredAccess As Long, _
ByVal dwFileOffsetHigh As Long, _
ByVal dwFileOffsetLow As Long, _
ByVal dwNumberOfBytesToMap As Long) As Long
#If VBA7 Then
Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (destination As Any, source As Any, _
ByVal length As Long)
#Else
Public Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (destination As Any, source As Any, _
ByVal length As Long)
#End If
Private Declare Function UnmapViewOfFile Lib "kernel32.dll" ( _
ByRef lpBaseAddress As Any) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
ByVal hObject As Long) As Long
Private hMMF As Long
Private pMemFile As Long
Sub IntoMemoryFileOutOfMemoryFile()
Dim sFile As String
Dim hFile As Long
sFile = "Z:\path\test1.txt"
hFile = CreateFile(sFile, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
hMMF = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 1000000, "MyMemoryMappedFile")
pMemFile = MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0)
Dim buffer As String
buffer = "testing1"
CopyMemory pMemFile, ByVal buffer, 128
hMMF = CreateFileMapping(-1, 0, PAGE_READWRITE, 0, 1000000, "MyMemoryMappedFile")
pMemFile = MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, 0)
Dim buffer2 As String
buffer2 = String$(128, vbNullChar)
CopyMemory ByVal buffer2, pMemFile, 128
MsgBox buffer2 & " < - it worked?"
UnmapViewOfFile pMemFile
CloseHandle hMMF
End Sub
Като малък пример кодът по-горе се опитва да постави низа "testing1" във файла test1.txt, след което извлича този низ и го съхранява в променлива buffer2 и накрая показва този низ чрез msgbox. Супер просто. Обаче нямам идея какво правя.
Всички наши компютри са 64-битови, Windows 7, Office/Excel 2013.
Проблеми/въпроси:
- Полето за съобщения е празно, когато стартирам IntoMemoryFileOutOfMemoryFile
- След като sub е завършен, отварям test1.txt и получавам: „Процесът няма достъп до файла, защото се използва от друг процес.“ Което ми казва, че не използвам UnmapViewOfFile и/или CloseHandle правилно.
- Бих искал да направя тези файлове с памет постоянни, така че ако всички компютри бъдат прекъснати, мога да рестартирам процеса и да продължа там, където съм спрял.
Ето някои от връзките, които използвах, за да стигна до мястото, където съм сега:
https://msdn.microsoft.com/en-us/library/dd997372%28v=vs.110%29.aspx
http://vb.mvps.org/hardcore/html/sharedmemorythroughmemory-mappedfiles.htm
http://www.tushar-mehta.com/publish_train/xl_vba_cases/1016%20Office%202010%20VBA.shtml
Интересна, но маловажна информация: "Проектът" е за клиент на хедж фонд. Аз съм финансист, който се е превърнал в фундаментално количество. Ние анализираме повече от 2000 акции на дневна база над 1250+ полета с данни, за да направим макроикономически сигнали/прогнози за покупка и продажба на акции, фючърси и опции.
АКТУАЛИЗАЦИЯ: Ако променя двата реда CopyMemory по този начин (предам pMemFile по стойност) съответно:
CopyMemory ByVal pMemFile, buffer, 128
и...
CopyMemory buffer2, ByVal pMemFile, 128
Получавам куп луди знаци във файла test1.txt и excel се срива.