forked from airat77786/MQL5Book
130 lines
5.1 KiB
MQL5
130 lines
5.1 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| GlobalsWithCondition.mq5 |
| |||
//| Copyright 2021, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#property service
| |||
| |||
#include "..\..\Include\PRTF.mqh"
| |||
| |||
// maximal number of concurrently running copies of the program
| |||
input int limit = 1; // Limit
| |||
input int startPause = 100; // Delay (ms)
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Delay emulation |
| |||
//+------------------------------------------------------------------+
| |||
void Delay()
| |||
{
| |||
if(startPause > 0)
| |||
{
| |||
Sleep(startPause);
| |||
}
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Service program start function |
| |||
//+------------------------------------------------------------------+
| |||
void OnStart()
| |||
{
| |||
PrintFormat("\nParameters: Limit: %d, Delay: %d", limit, startPause);
| |||
// create new temporary variable if it's not exist
| |||
// keep current value otherwise
| |||
PRTF(GlobalVariableTemp(__FILE__));
| |||
| |||
// precondition guards
| |||
int count = (int)GlobalVariableGet(__FILE__);
| |||
if(count < 0)
| |||
{
| |||
Print("Negative count detected. Not allowed.");
| |||
return;
| |||
}
| |||
| |||
if(count >= limit)
| |||
{
| |||
PrintFormat("Can't start more than %d copy(s)", limit);
| |||
return;
| |||
}
| |||
| |||
const int maxRetries = 5;
| |||
int retry = 0;
| |||
| |||
while(count < limit && retry < maxRetries)
| |||
{
| |||
// emulate slow execution in busy conditions,
| |||
// where multiple programs run in parallel
| |||
Delay();
| |||
if(PRTF(GlobalVariableSetOnCondition(__FILE__, count + 1, count))) break;
| |||
// conditional assignment failed, try again with updated base value
| |||
count = (int)GlobalVariableGet(__FILE__);
| |||
PrintFormat("Counter is already altered by other instance: %d", count);
| |||
retry++;
| |||
}
| |||
| |||
if(count == limit || retry == maxRetries)
| |||
{
| |||
PrintFormat("Start failed: count: %d, retries: %d", count, retry);
| |||
return;
| |||
}
| |||
| |||
// work cycle (mockup)
| |||
int loop = 0;
| |||
while(!IsStopped())
| |||
{
| |||
PrintFormat("Copy %d is working [%d]...", count, loop++);
| |||
// ...
| |||
Sleep(3000);
| |||
}
| |||
| |||
retry = 0;
| |||
int last = (int)GlobalVariableGet(__FILE__);
| |||
while(last > 0 && retry < maxRetries)
| |||
{
| |||
PrintFormat("Copy %d (out of %d) is stopping", count, last);
| |||
Delay();
| |||
if(PRTF(GlobalVariableSetOnCondition(__FILE__, last - 1, last))) break;
| |||
last = (int)GlobalVariableGet(__FILE__);
| |||
retry++;
| |||
}
| |||
| |||
if(last <= 0)
| |||
{
| |||
PrintFormat("Unexpected exit: %d", last);
| |||
}
| |||
else
| |||
{
| |||
PrintFormat("Stopped copy %d: count: %d, retries: %d", count, last, retry);
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
/*
| |||
example output
| |||
| |||
GlobalsWithCondition 2 GlobalVariableTemp(GlobalsWithCondition.mq5)=false / GLOBALVARIABLE_EXISTS(4502)
| |||
GlobalsWithCondition 1 GlobalVariableTemp(GlobalsWithCondition.mq5)=false / GLOBALVARIABLE_EXISTS(4502)
| |||
GlobalsWithCondition GlobalVariableTemp(GlobalsWithCondition.mq5)=true / ok
| |||
GlobalsWithCondition GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,count+1,count)=true / ok
| |||
GlobalsWithCondition 1 GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,count+1,count)=false / GLOBALVARIABLE_NOT_FOUND(4501)
| |||
GlobalsWithCondition 2 GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,count+1,count)=false / GLOBALVARIABLE_NOT_FOUND(4501)
| |||
GlobalsWithCondition 1 Counter is already altered by other instance: 1
| |||
GlobalsWithCondition Copy 0 is working [0]...
| |||
GlobalsWithCondition 2 Counter is already altered by other instance: 1
| |||
GlobalsWithCondition 1 GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,count+1,count)=true / ok
| |||
GlobalsWithCondition 1 Copy 1 is working [0]...
| |||
GlobalsWithCondition 2 GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,count+1,count)=false / GLOBALVARIABLE_NOT_FOUND(4501)
| |||
GlobalsWithCondition 2 Counter is already altered by other instance: 2
| |||
GlobalsWithCondition 2 Start failed: count: 2, retries: 2
| |||
GlobalsWithCondition Copy 0 is working [1]...
| |||
GlobalsWithCondition 1 Copy 1 is working [1]...
| |||
GlobalsWithCondition Copy 0 is working [2]...
| |||
GlobalsWithCondition 1 Copy 1 is working [2]...
| |||
GlobalsWithCondition Copy 0 is working [3]...
| |||
GlobalsWithCondition 1 Copy 1 is working [3]...
| |||
GlobalsWithCondition Copy 0 (out of 2) is stopping
| |||
GlobalsWithCondition GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,last-1,last)=true / ok
| |||
GlobalsWithCondition Stopped copy 0: count: 2, retries: 0
| |||
GlobalsWithCondition 1 Copy 1 (out of 1) is stopping
| |||
GlobalsWithCondition 1 GlobalVariableSetOnCondition(GlobalsWithCondition.mq5,last-1,last)=true / ok
| |||
GlobalsWithCondition 1 Stopped copy 1: count: 1, retries: 0
| |||
*/
| |||
//+------------------------------------------------------------------+
|