Mt4 - the Terminal that never sleeps :(

 

I wanted the EA to coordinate file accesses using GetTickCount(). So I was testing what it can do and got this:


It should sleep for 7 mSec but it never sleeps. Here is my EA, where am I mistaken??  Or is this just the reason why the terminals are so fast - the timer are influenced by the theories of relativity of Einstein?

//+------------------------------------------------------------------+
//|                                              test_mSec_Sleep.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
extern int mSec = 10000;
extern int RandVal = 20;
uint maxmSec = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(mSec);
   MathSrand(GetTickCount()); 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   uint beg0 = GetTickCount(),       // get mSec-Time
        begM = beg0%10,              // 
        slp  = begM>3 ? 11-begM : 0; // start to calc if begM <= 3
   if ( begM>3 )  Sleep(slp);
   uint dur,beg=GetTickCount();      // new mSec-Time after Sleep

   int i = MathRand()%RandVal;
   while(i-->0) {
      double x = MathLog(i+2); // just to spend some time here
   }
 
   dur=GetTickCount()-beg;       // find the time of calc..
   maxmSec = fmax(dur,maxmSec);  // save the max
   Comment(beg0,": ",beg," => ",dur," begM: ",begM,"  slp: ",slp,"  max: ",maxmSec,"  ",TimeCurrent());
   return;   
  }
//+------------------------------------------------------------------+

May be - due to be as fast as possible - the Sleep()-order was put in another thread?

dur is always 0 (on my 10 years old laptop) despite there was in the screen shot the order to sleep for 7 mSec?

beg0 and beg are always the same despite there was in the screen shot the order to sleep for 7 mSec?

Even if you set RandVal to 30000 dur stays always 0 and the maxmSec too - wow the terminal never sleeps.

You can even replace int i = MathRand()%RandVal; by int i = 30000; //MathRand()%RandVal; - the terminal never sleeps.

The next update might be able to finish before it was started and the final GetTickCount() is smaller than the initial ;)

theory of relativity - Deutsch-Übersetzung – Linguee Wörterbuch
theory of relativity - Deutsch-Übersetzung – Linguee Wörterbuch
  • www.linguee.de
Electromagnetic Field Theory and the Theory of Relativity on the other hand can be solved in favour of Field Theory and Relativity - if it is possible Feldtheorie mit Relativitätstheorie andererseits werden zugunsten der elektromagnetischen Feldtheorie und der Relativitätstheorie aufgelöst, Wandlung von Vakuumenergie in eine andere...
 
Carl Schreiber:

I wanted the EA to coordinate file accesses using GetTickCount(). So I was testing what it can do and got this:


It should sleep for 7 mSec but it never sleeps. Here is my EA, where am I mistaken??  Or is this just the reason why the terminals are so fast - the timer are influenced by the theories of relativity of Einstein?

May be - due to be as fast as possible - the Sleep()-order was put in another thread?

dur is always 0 (on my 10 years old laptop) despite there was in the screen shot the order to sleep for 7 mSec?

beg0 and beg are always the same despite there was in the screen shot the order to sleep for 7 mSec?


This isn't long enough (takes less than a millisecond). It is after the sleep

uint dur,beg=GetTickCount();      // new mSec-Time after Sleep

   int i = MathRand()%RandVal;
   while(i-->0) {
      double x = MathLog(i+2); // just to spend some time here
   }
 
   dur=GetTickCount()-beg;       // find the time of calc..

When i is printed, the values are 9, 17 etc.

Maybe use GetMicrosecondCount() or make the loop longer?

 

Thank you - GetMicrosecondCount() is new to me, but Sleep sleeps for mSecs and both mSec from GetTickcount() before and after the Sleep are the same - how can that be?

The log-calculation is only to spent some time - its not important to me.

 

The behaviour seems normal to me:

void OnTimer()
  {
   uint begin=GetTickCount();
   Sleep(500);
   uint end = GetTickCount();
   Comment(StringFormat("Begin: %i\nEnd: %i\nDuration: %i",begin,end,end-begin));
  }

 

Edit: OK, I think I see what you mean.

If you use a large number (like 500), no problem - see above.

But if you use smaller values you end up with either 15 / 16 because of the system timer limitations, or 0.



void OnTimer()
  {
   static int sleep=15;
   static int cnt  =0;
   uint begin=GetTickCount();
   Sleep(sleep);
   uint end = GetTickCount();
   printf("Sleep: %i Begin: %i End: %i Dur: %i",sleep,begin,end,end-begin);
   cnt++;
   if(cnt>3)
     {
      sleep-=2;
      cnt = 0;
     }
   if(sleep<5) EventKillTimer();
  }
 

Hmm,

if you use this version Sleep turns out to be some kind of a random timer.

  1. Sleep below a certain number is ignored
  2. and even Sleep(100) is only sometimes 100, sometimes faster, sometimes slower..

Could it be that Windows (below the mt4) tries to be tricky?

//+------------------------------------------------------------------+
//|                                              test_mSec_Sleep.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
extern int mSec = 10000;
uint maxmSec = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetMillisecondTimer(mSec);
   MathSrand(GetTickCount()); 
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+

void OnTimer()
  {
   //ulong beg0 = GetMicrosecondCount(),begM = beg0%10, slp = begM>3 ? 11-begM : 0;
   /*L 1*/uint beg0 = GetTickCount(),begM = beg0%10, slp = begM>3 ? 11-begM : 0;
   if ( begM>3 )  Sleep((int)slp);
   /*L 3*/uint dur,beg=GetTickCount(); 
   
   /*L 5*/Sleep(100);
 
   /*L 7*/dur=GetTickCount()-beg;
   maxmSec = fmax((int)dur,maxmSec);  // uint beg0 = GetTickCount(),begM = beg0%10, slp = begM>3 ? 11-begM : 0;
   Comment("OnTime()  ",TimeCurrent(),"\nL 1: ",beg0," mSec, ",beg0,"%10 = ",begM," => Sleep : ",slp," mSec  \nL 3: ",beg," mSec   expected: ",(beg0+slp),
           "\nL 5: ",dur," mSec  Duration after Sleep(100)\nGetTickCount right now ",GetTickCount());
   return;
   
  }
 

The Service desk just told me:

"It depends on system clock resolution in the Intel architecture.
There is very known issue with some inaccuracy of system clock - deviation can be up to 15 milliseconds"

Sigh :(

If so even GetMicrosecondCount() does not help!

What a rainy day today.

 
Carl Schreiber:

The Service desk just told me:

"It depends on system clock resolution in the Intel architecture.
There is very known issue with some inaccuracy of system clock - deviation can be up to 15 milliseconds"

Sigh :(

If so even GetMicrosecondCount() does not help!

What a rainy day today.


Have a read of this thread. I found that you could drop the sleep but not the timer.

What I find strange here is the randomness of whether it is 0 or 15ms. 

 
Carl Schreiber: I wanted the EA to coordinate file accesses using GetTickCount(). So I was testing what it can do and got this:

This entire thread is useless. Using sleep (any version) will still result in a race condition between two separate processes.

  1. If you are coordinating access between to EAs, See my mutex Prevent EA from opening trades at the same time across 2 or more pairs? (Steve) - MQL4 forum
  2. If it is external, access the file with exclusive read privileges and/or delete the file after read.
 
whroeder1:

race condition between two separate processes.

A thread race is not my problem, but the access of two processes to the same file and my idea instead of looping while h==INVALID_HANDLE I wanted one process to access from 0-4 and the other one from 5-9. Should be easy - theoretically - as both processes´need to open, read/write and close the file always 0 mSec. Well, but there is Intel's minimal resolution of 15 mS.

And "this entire thread is .. " not [ed. note]  ".. useless" as at least I learnt about this minimal resolution and I do now understand that many calculations within OnTimer or OnCalculate take either 0 mSec or 15 mSec or 31 MSec ... 

Reason: