MQ мельком упоминал, что Sleep на уровне винды немного паралелит
Сначала функция вообще пустая была, работало с тем же результатом (т.е. тупо терминал вылетал целиком)
Добавил sleep для теста мьютексов, запускал скрипт на двух графиках и проверял как они синхронизируются
Указатель на функцию в MQL не тоже самое что в обычном С?
Именно так.
Озадачился вопросом как вынести тяжелый но не критичный процесс в отдельный поток
В MQL отдельные потоки можно организовать только запуском дополнительного эксперта или (в ограниченных случаях) скрипта. Передавать команды и данные туда/сюда можно разными способами - на форуме уже обсуждались.
Ну тогда уж лучше внешнюю либу куда данные копировать и запускать поток
Возни чуть больше, зато надежнее
Ну тогда уж лучше внешнюю либу куда данные копировать и запускать поток
Возни чуть больше, зато надежнее
Это не надежнее, а единственный вернуть способ.
Пробую идти по единственно верному пути, и что-то спотыкаюсь
Делаю DLL с иcпользованием Qt
#include <QtGlobal> #include <QtCore> #include <QtMath> #include <QtConcurrent/QtConcurrent> #include <windows.h> #define MQL_EXPORT extern "C" __declspec(dllexport) #define MT4_WMCMD_UPDATE_DATA 33324 QFuture<void> F; // Пока тестирую с одним индикатором, можно просто глобальную переменную использовать // Просто ради теста MQL_EXPORT int test(int a, int b) { return a+b; } // Заполнение переданного буфера значениями в отдельном потоке void fill(HWND hwnd, UINT msg, double v[], int len) { QThread::sleep(3); for (int i = 0; i < len; ++i) v[i] = qrand()%500; } MQL_EXPORT bool wait() { F.waitForFinished(); return true; } // Здесь происходит запуск потока MQL_EXPORT int random(HWND hwnd, UINT msg, double v[], int len) { if (F.isRunning()) return 0; F = QtConcurrent::run(fill, hwnd, msg, v, len); return 1; }
Код индикатора
#property strict #property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 //--- plot L #property indicator_label1 "L" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 #import "dlltest.dll" int random(int hwnd, uint msg, double &v[], int len); bool wait(); #import //--- indicator buffers double L[]; int hwnd; uint msg; int OnInit() { SetIndexBuffer(0, L); hwnd = WindowHandle(Symbol(), Period()); msg = 0; Print(__LINE__); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print(__LINE__); wait(); Print(__LINE__); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { Print(__LINE__); static int it = 0; int res = random(hwnd, msg, L, ArraySize(L)); Comment(++it, " ", res); Print(__LINE__); return(rates_total); }
И вот это все даже работает, но когда пытаюсь удалить индикатор, терминал виснет
Из OnDeinit принтов нет
В функции random идет проверка есть ли что-то в процессе или нет, если есть, то пропускаем вызов, если нет - запускаем поток на заполнение буфера
Пробовал создавать промежуточный буфер который заполняется данными в выделенном потоке и потом когда уже поток завершился генерируется событие OnTimer и внутри индикатора копируются данные обратно. Работает аналогично, т.е. данные приходят и все обновляется, но при попытке удалить индикатор терминал виснет намертво
В чем может быть проблема?
Пробую идти по единственно верному пути, и что-то спотыкаюсь
Делаю DLL с иcпользованием Qt
Код индикатора
И вот это все даже работает, но когда пытаюсь удалить индикатор, терминал виснет
Из OnDeinit принтов нет
В функции random идет проверка есть ли что-то в процессе или нет, если есть, то пропускаем вызов, если нет - запускаем поток на заполнение буфера
Пробовал создавать промежуточный буфер который заполняется данными в выделенном потоке и потом когда уже поток завершился генерируется событие OnTimer и внутри индикатора копируются данные обратно. Работает аналогично, т.е. данные приходят и все обновляется, но при попытке удалить индикатор терминал виснет намертво
В чем может быть проблема?
С Qt не работал, но что-то мне подсказывает, что:
F.waitForFinished();
не дает указаний на остановку потока, а только ждет его завершения. А раз так, то поток остается активным, из-за чего и происходит зависание.
Из OnDeinit принтов нет
ни перед функцией ни после? как ведет себя в дебаг режиме?
как вариант принтов может не быть как раз из-за того что терминал виснет, а виснет он скорее всего уже после OnDeinit, потому что я не верю что waitForFinished без задачи может устроить дедлок
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Всем привет
Озадачился вопросом как вынести тяжелый но не критичный процесс в отдельный поток
MQL позволяет загружать функции из DLL
kernel32 содержит разные примочки для многопоточности, решил поэкспериментировать
Пишу следующий код
Комилится и работает до тех пор пока не приходит пора вызова своей функции
Терминал просто вылетает на ResumeThread (там вместо CREATE_NORMAL - CREATE_SUSPENDED, при флаге CREATE_NORMAL поток запускается сразу и тоже вылетает)
В чем может быть проблема? Указатель на функцию в MQL не тоже самое что в обычном С? Что я упускаю?
Пробовал работать с мьютексами, там все норм, типы вроде все правильно переопределил, указатели - просто адреса (числа) на область памяти и для 32 версии используется int, если использовать long то проблемы с DLL