Atomic Global Variables are not atomic

 

I have a robot of my own construction working on several charts at the same time, and I wanted all of them to write to a common log file. The problem was that it wouldn't wait till the others had finished writing before starting to write, so the log file was full of partially overwritten lines.

I wrote a semaphore/locking implementation to overcome the problem but it never worked. It went something like this.

GlobalVariableTemp("lockvar");

GlobalVariableSetOnCondition("lockvar",1,0);

write stuff

GlobalVariableSet("lockvar",0);

but it just went on merrily overwriting partial lines in the log file.

I did everything I could think of, I tested the error output from all the GlobalVariable functions, and you know what, GlobalVariableSetOnCondition never returned any error whatsoever, which logically means that it always found the variable contents to be 0, which given the frequency of the partially overwritten lines does seem strange.

Maybe the global var stuff is fine, maybe the file writing functions are passing the work on to other threads that are messing things up. I don't know, but either way it is a pain in the behind.

In the end, I just ended up Print("ing") a ton of stuff to the experts console, and then filtering the contents of the saved logfiles.

 

Maybe you try the token ring approach where only the one that has the specific ID or token is allowed to speak and once it's done it passes the token to the next ID so it can then speak.

A bit work to set up but in the end you have just one that can modify the file at a time, but all are given the chance to speak one after the other.

 
Marco vd Heijden:

Maybe you try the token ring approach where only the one that has the specific ID or token is allowed to speak and once it's done it passes the token to the next ID so it can then speak.

A bit work to set up but in the end you have just one that can modify the file at a time, but all are given the chance to speak one after the other.

That is exactly what I was trying to do, and it wasn't working.

I then tested the global variable atomic write stuff without trying to write to a file and I got no errors whatsoever.

I run MT4 on linux in wine and I am not certain it is writing stuff to files in the order I ask it to. Writes from a single thread are fine, but when the EA is running on several charts at once, the token ring approach wasn't enough to ensure consistent write order. 

If I do Sleep(1000) after writing and before allowing another thread to write, then it seems to work as it should.

Global variables are great! 

 

GlobalVariableTemp("lockvar");

GlobalVariableSetOnCondition("lockvar",1,0);

write stuff

GlobalVariableSet("lockvar",0);

You must  lock, write, and close the file so the contents are written to disk, before unlocking. Your mutex is fine, but you aren't completing the write operation before.
 
Jimmy Tee:

...

I did everything I could think of, I tested the error output from all the GlobalVariable functions, and you know what, GlobalVariableSetOnCondition never returned any error whatsoever, which logically means that it always found the variable contents to be 0, which given the frequency of the partially overwritten lines does seem strange.

...

You only have to check the return value, why do you care about any error ?

If true the gv is changed, you have a lock, if false not changed, you have to wait.

See the link above. If you still have difficulties, please show your actual code.

MQL5 Programming Basics: Global Variables of the Terminal
MQL5 Programming Basics: Global Variables of the Terminal
  • 2016.11.25
  • Dmitry Fedoseev
  • www.mql5.com
Global variables of the terminal provide an indispensable tool for developing sophisticated and reliable Expert Advisors. If you master the global variables, you will no more be able to imagine developing EAs on MQL5 without them.
 
whroeder1:

GlobalVariableTemp("lockvar");

GlobalVariableSetOnCondition("lockvar",1,0);

write stuff

GlobalVariableSet("lockvar",0);

You must  lock, write, and close the file so the contents are written to disk, before unlocking. Your mutex is fine, but you aren't completing the write operation before.

Not sure. Where is the gv initialized ? Where is GlobalVariableSetOnCondition()  return value checked ?