Jump to content
Sign in to follow this  
Л_Е_О

MMF - обмен данными между терминалами, советниками через виртуальные файлы ?!

Recommended Posts

AntFX

Смысла особенного в этих плясках с бубном сейчас нет, поскольку обмен файлами между терминалами можно делать теперь уже давно штатными средствами с помощью флага FILE_COMMON, и занимает этот процесс не больше нескольких миллисекунд, т.е. подходит для 99.9% любых возможных задач под МТ

Edited by AntFX
  • Thanks 1

1

Share this post


Link to post
Share on other sites
Aequo_animo

   Ну это всё равно что спорить , что лучше коммунизм или капитализм . Этот метод не чуть не сложнее работы с файлами. Считайте ,сразу бах и массив скопирован , вся структура . Можно насоздавать сколько угодно таких массивов разного типа и большего размера . По количеству использованных функций вряд ли данный способ превышает работу с файлами . 

   Я с файлами тоже буду вынужден работать (ну или с глобальными переменными), потому как ноут мой работает только от сети , да и мало ли просто перезагрузиться . 

   По быстро действию надо ставить эксперименты . Но мне лень и мне хватает . Исхожу из неочевидного факта , что используются  только  стандартные виндовс библиотеки , вроде как долго не должно быть .

Share this post


Link to post
Share on other sites
Player 2

 

 

По быстро действию надо ставить эксперименты . Но мне лень и мне хватает

По быстродействию это самый быстрый способ обмена данными между приложениями в винде (по крайней мере так написано в какой-то книге, не помню её названия, сам я не проверял, но оснований не доверять автору нет).

 

 

 

Единственно уточню , если массив будет слишком большой и операционка разместит его в памяти не подряд , а в разные области , передать его весь функцией memmove не получиться .

Такого не должно быть по идее. У Вас такое в реале получалось?

Share this post


Link to post
Share on other sites
Aequo_animo

 

 

Такого не должно быть по идее. У Вас такое в реале получалось?

    У меня не получалось , я большие массивы не создавал . Это оговорка на всякий случай , т.к. логика функции memmove такова , что она из одно адреса копирует в другой адрес указанное количество байт (бинарных данных) без какой либо проверки , лишь бы были права доступа . Поэтому если операционка либо сам метатрейдер из-за большого размера поместит массив не подряд , то не получится скопировать весь. Там где-то в дебрях программирования есть понятие "гранулярность памяти" , типа неделимость . Если она к примеру 4096 байт ,то это одно ;если 1024 , то другое ; если 32768 байт , то третье . Где это узнать я не знаю . Если массив из 10 000 элементов , да 8 байт каждый , такой массив может раскидать по разными областям , и метод тогда этот не применим .

Share this post


Link to post
Share on other sites
Player 2

 

 

Поэтому если операционка либо сам метатрейдер из-за большого размера поместит массив не подряд , то не получится скопировать весь.

Если массив из 10 000 элементов , да 8 байт каждый , такой массив может раскидать по разными областям , и метод тогда этот не применим .

Разместить массив не подряд нельзя, это спецификация C++. Он всегда цельный. Массив из 10К элементов (как и какой-либо другой) не может раскидать по областям.

Файл всегда отображается тоже без разрывов.

  • Thanks 2

Share this post


Link to post
Share on other sites
Aequo_animo

  

 

Разместить массив не подряд нельзя, это спецификация C++. Он всегда цельный. Массив из 10К элементов (как и какой-либо другой) не может раскидать по областям. Файл всегда отображается тоже без разрывов.

  Ну значит тем более нет никаких проблем . Если под словом "отображается"  понимается размещение в физической оперативной памяти "без разрывов". Возможно так оно и есть,  просто не спец , я не знаю . 

Share this post


Link to post
Share on other sites
Player 2

 

 

Если под словом "отображается" понимается размещение в физической оперативной памяти "без разрывов".

В физической памяти разрывы могут быть (если имеется ввиду действительно физическая память, а не виртуальная. То с чем работаем мы - виртуальная). Под "отображается" имеется ввиду отображение в виртуальное адресное пространство процесса - с которым (адресным пространством) мы и работаем. К физической памяти имеет доступ сама винда, а не процесс.

Share this post


Link to post
Share on other sites
Aequo_animo

  Ага , значит я не зря боялся , слова "отображается" . Потому как это абстракция , мне как не программисту , сложна для восприятия , так и думал , что тут какая-то собака зарыта . Мы подключаем 2 библиотеки , одна из которых по работе с виртуальными файлами , а другая не знаю с чем  ))) . И по моему вторая не имеет отношения непосредственно к виртуальным файлам . Я как понял , что memmove просто переносит блок памяти из одного места в другое , в не зависимости от виртуальный это файл или любой другой . Для этого мы передаём в качестве аргументов именно адреса физической памяти .

  Я пробовал через Print распечатать , что возвращает CreateFileMappingA и что возвращает MapViewOfFile. Первая возвращает небольшое число , действительно хендл процесса . А вторая очень большое число (там миллионы) , что действительно похоже на физический адрес .

  Вообще мне и самому не понятно , почему нам не достаточно только методов по работе именно с виртуальными файлами . Зачем нам нужен этот memmove !? Вот поэтому я и указал автора изначального метода , потому как я не автор , а просто попугай ))). Всё что я сделал , это из его длл вытащил наружу функцию которую он использовал .

Share this post


Link to post
Share on other sites
Aequo_animo

  Пол часа пытался найти пример где указатель для memmove рассчитывался исходя из гранулярности памяти , но так и не нашёл , а в описании к функции почему-то этого не упоминается , что надо учитывать гранулярность . 

Share this post


Link to post
Share on other sites
Player 2

. Мы подключаем 2 библиотеки , одна из которых по работе с виртуальными файлами , а другая не знаю с чем ))) . И по моему вторая не имеет отношения непосредственно к виртуальным файлам .

Вторая содержит функцию memmove, судя по коду.

 

 

 

Зачем нам нужен этот memmove !? Вот поэтому я и указал автора изначального метода , потому как я не автор , а просто попугай ))). Всё что я сделал , это из его длл вытащил наружу функцию которую он использовал .

В принципе там всё правильно. Создается или открывается файл (CreateFileMappingA), делается его отображение в адресное пространство процесса (MapViewOfFile), в "передатчике" делается копирование из массива в этот файл (memmove), в "приемнике" делается копирование из файла в свой массив.

Постоянно отображать файл в цикле (т.е. вызывать MapViewOfFile) не обязательно, это можно сделать один раз после CreateFileMappingA, и потом один раз вызвать UnmapViewOfFile перед CloseHandle в функции deinit. Это единственное замечение по коду (хотя нет, не единственное, см. ниже).

Вся гранулярность памяти в Вашем случае заключается в указании количества байт функции memmove кратному размеру массива B (или St), который состоит из double. Тип double это 8 байт и это и есть "гранула" в Вашем случае. Вместо 256 можно было написать длину массива B (или St) умноженную на 8, что и сделано, но уже в виде результата этого умножения, а не как вычисляющееся на лету выражение (что было бы что-то типа arrayLength*8 ). То же касается указания размера файла функциям CreateFileMappingA и MapViewOfFile.

 

 

 

Зачем нам нужен этот memmove !?

Чтобы скопировать данные из файла в массив в MQL, с которым уже можно будет работать как с массивом. Не знаю можно ли в MQL работать напрямую с произвольной памятью (и как следствие с разделяемым файлом), если можно - то копирование не обязательно и можно брать данные напрямую.

 

Теперь еще одного замечание по коду. Ваш код не учитывает порождаемое состояние гонки между процессами (aka race condition). В нем два процесса изменяют один файл, и это потенциально может привести к тому что "приемник" скопирует данные в момент времени когда "передатчик" всё еще пишет их, из-за чего данные могут оказаться искаженными и с малопредсказуемым содержимым. Случаться это будет очень редко, но когда будет - Вы будете очень долго ломать голову над тем что же произошло. Поэтому в этих случаях нужно использовать Mutex, а это отдельный геморрой. У того автора было слово Mutex в коде? Если да, то Вы зря его пропустили.

Edited by Player 2

Share this post


Link to post
Share on other sites
AntFX
Ну это всё равно что спорить , что лучше коммунизм или капитализм

Этот способ заведомо хуже работы с файлами сразу по нескольким причинам:

- он значительно сложнее технологически (для работы с файлами не нужно разбираться в низкоуровневых функциях, достаточно знания простого MQL)

- для него необходимо включение dll (это минус к любой программе на MQL, если можно обойтись без dll, нужно без них обходиться - это вопрос безопасности)

- насколько я понимаю, при перезагрузке данные теряются, т.е. если нужно сохранять данные между перезапусками программы (а это нужно чаще всего), то обычные файлы все равно придется задействовать, производя уже дублирующую работу по сохранению и загрузке из "виртуальных" файлов в обычные

 

Из плюсов - только быстродействие, но на MQL фактически нет таких задач, которые требуют сверхбыстродействия.

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Player 2

dll там используются стандартные виндовые, почти наверняка сам MT4 их использует.

Данные теряются уже при закрытии обоих приложений (приемника и передатчика одновременно), даже без перезагрузки. (UPD: данные будут потеряны при деинициализации обоих советников.) Но можно сделать отображение реального файла с диска в память, и тогда все данные будут на диске параллельно с памятью.

Я использовал такой обмен именно для того чтобы не создавать файлы на диске. Это мусор и им нужно указывать пути (что нудно). Хотя memory-mapped-файлам тоже нужно указывать имена, но они более короткие и приятнее смотрятся, и потом эти файлы исчезают без следов не занимая места и не вызывая вопросов что это и нужно ли это, в отличие от того как это происходит с файлами обмена, которые остаются на диске даже когда система которая их использовала уже давно слила все деньги и трейдер забыл что это вообще такое.

Быстродействие на MT4 действительно не нужно.

Короче, это больше вопрос эстетики.

Edited by Player 2

Share this post


Link to post
Share on other sites
AntFX
Это мусор и им нужно указывать пути (что нудно)

Да не нужно им ничего указывать, только название файла. Пути все стандартные, обращение стандартными функциями MQL

 

dll там используются стандартные виндовые, почти наверняка сам MT4 их использует.

Это Вам понятно, к тому же, только когда код открыт 

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Player 2
Когда код закрыт, это пользователю не узнать никак.

При закрытом коде (если речь про ex4) будет видно наличие или отсутствие dll всё равно. Эти файлы можно использовать с помощью стандартных виндовых dll, так что ex4 будет идти без dll.

Edited by Player 2

Share this post


Link to post
Share on other sites
Aequo_animo

 

 

У того автора было слово Mutex в коде?

Весь код который скрыт в mmf.dll представлен в конце поста  https://forum.alpari.com/index.php?/topic/49806-mmf-obmen-dannymi-mezhdu-terminalami-sovetnikami/?p=2543653. Больше там ничего нет .

 

В нем два процесса изменяют один файл, и это потенциально может привести к тому что "приемник" скопирует данные в момент времени когда "передатчик" всё еще пишет их

Я об этом тоже думал , но это за гранью моих знаний .

Share this post


Link to post
Share on other sites
AntFX
Эти файлы можно использовать с помощью стандартных виндовых dll, так что ex4 будет идти без dll.

С помощью стандартных dll можно сделать не меньше гадостей, ну о чем мы спорим :) Если программа для себя - без разницы, что ты туда пихаешь, если её потом публиковать где-то планируется, то если можно без длл обойтись, лучше обойтись. К тому же стандартные файлы это однозначно проще - вы тут до мутексов дошли уже...

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Player 2
Да не нужно им ничего указывать, только название файла. Пути все стандартные, обращение стандартными функциями MQL

У меня был обмен не между двумя MT4, а между MT4 и другим приложением, которому мне всё равно пришлось бы указывать полный путь. Но это вопрос эстетики, как я уже сказал.

 

 

 

Я об этом тоже думал , но это за гранью моих знаний .

Если интересно, я могу написать какие нужны исправления.

 

 

 

К тому же стандартные файлы это однозначно проще - вы тут до мутексов дошли уже...

Это да. Но при обмене через файлы тоже может быть эта же самая проблема, всё зависит от того в каком режиме они открываются.

Share this post


Link to post
Share on other sites
Aequo_animo

 

 

он значительно сложнее технологически

А для меня он заведомо легче , причём намного  ))) ... потому-что я разобрался  

Share this post


Link to post
Share on other sites
AntFX

А для меня он заведомо легче , причём намного  ))) ... потому-что я разобрался  

Ну-ну, разобрались и данные пропадают почему-то :)

 

 

У меня был обмен не между двумя MT4, а между MT4 и другим приложением

Ну это уже другое дело... 

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Aequo_animo

 

 

Если интересно, я могу написать какие нужны исправления.

Спасибо , пока буду рассчитывать на  авось . 

 

Ну-ну, разобрались и данные пропадают почему-то

У меня давненько работал копировщик по этому методу , сбоев не было . Хотя не спорю может и учитывал какие-то нюансы .

Share this post


Link to post
Share on other sites
AntFX
при обмене через файлы тоже может быть эта же самая проблема, всё зависит от того в каком режиме они открываются.

Если проблема - изменение одного файла разными процессами, то вообще не понимаю, зачем такое нужно. Как правило - одна программа = 1 файл для записи, например источник (копирования сделок) пишет свой файл, а получатель его только читает. Если есть подозрение, что можно прочитать файл раньше, чем он будет полностью записан, можно в конец какой-нибудь маркер добавить... Если источников несколько, будет несколько файлов с разными номерами счетов. После прочтения получатель удаляет файл и источник т.о. получает команду на запись нового. Думаю, при такой схеме каких-то регулярных проблем быть не может.

 

При этом это все работает без доп. геморроя с длл. У меня в архиве с корректировщиком лежит библиотека, в которой это все удобно реализовано через ООП. Может как-нибудь соберусь сделать специальное руководство по теме обмена данными на основе этой библиотеки... Потому что инструмент универсальный и нужен почти в любой серьезной программе на MQL. Давно хотел, но руки пока не доходят

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Player 2
Если есть подозрение, что можно прочитать файл раньше, чем он будет полностью записан, можно в конец какой-нибудь маркер добавить

В том-то и дело, что это будет та же проблема что и у memory-mapped-файлов, и маркером она не решается.

Файл можно открывать в режиме, когда доступ к нему имеет только один процесс, и пока файл открыт им, другие процессы открыть его не могут. В этом случае мьютекс не нужен, т.к. режим открытия файла выполняет его функцию. Но можно ли в MQL указывать режим открытия файла я не помню.

 

Я одно время торговал через терминал, который в качестве экспорта данных пишет текстовые файлы. Он просто дописывает файл в конец в течение всей сессии - этот вариант работает без мьютекса.

Edited by Player 2

Share this post


Link to post
Share on other sites
AntFX
В том-то и дело, что это будет та же проблема что и у memory-mapped-файлов, и маркером она не решается.

Не очень понял, что за проблема, тогда. Если не изменяют файл несколько разных процессов, какая может быть проблема? 

 

 

Но можно ли в MQL указывать режим открытия файла я не помню.

Можно указывать режим, но режим совместного чтения удобен и я не вижу смысла от него отказываться ) 

Edited by AntFX

1

Share this post


Link to post
Share on other sites
Player 2

 

 

Не очень понял, что за проблема, тогда. Если не изменяют файл несколько разных процессов, какая может быть проблема?

Да не, всё та же проблема - изменение файла несколькими потоками.

Схема с маркером и удалением файла (я еще на первую версию поста отвечал) должна работать нормально.

Share this post


Link to post
Share on other sites
AntFX

Да и маркер чаще всего не нужен- я не сталкивался с практической необходимостью и потерей данных, во всяком случае, написав несколько копировщиков и без использования маркеров...


1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×