Click here to Skip to main content
15,665,166 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
[Detai of logic code as below]
C++
- In C++ project(TestProject.exe)
  private ref class TestStaticClass
  {
      static int _testStaticVariable = 5;
  }

  int main()
  {
      cli::array<string^>^ arguments = Environment::GetCommandLineArgs();
      String^ fileName = arguments[0];

      ofstream* ofstreamTest = new ofstream();
      ofstreamTest->open(String::Concat(fileName, ".txt"), ios::out | ios::app);
      if (ofstreamTest->is_open())
      {
          cout.rdbuf(ofstreamTest->rdbuf());
      }
      for (int i = 0; i < 1000000; i++)
      {
          cout << TestStaticClass::_testStaticVariable; (*)
          cout << "\n";
          TestStaticClass::_testStaticVariable++; (**)
      }
      if (ofstreamTest != NULL)
      {
          ofstreamTest->close();
          delete ofstreamTest;
      }
  }


=> Run below command by Command Prompt
[TestProject.exe "TestFile"]
Then, TestFile.txt is outputted with below content:
5
6
...
1000004

- In C# project, logic code as below:
C#
public void ExecOne(string fileName)
  {
     ProcessStartInfo processStartInfo = new ProcessStartInfo("TestProject.exe");
     processStartInfo.WorkingDirectory = "C:\TestApplication\";
     processStartInfo.Arguments = $"\"{fileName}\"";
     processStartInfo.CreateNoWindow = true;
     processStartInfo.UseShellExecute = false;
     processStartInfo.RedirectStandardInput = false;
     processStartInfo.RedirectStandardOutput = true;

     Process process = Process.Start(processStartInfo);
  }

  public void ExecAutoCheck()
  {
     ParallelOptions parallelOptions = new ParallelOptions();
     parallelOptions.MaxDegreeOfParallelism = 3;
     
     var action1 = () => ExecOne("FileNameTest1");
     var actions = () => ExecOne("FileNameTest2");
     var action3 = () => ExecOne("FileNameTest3");
     List<action> listActionParallel = new List<action>();  
     listActionParallel.Add(action1);
     listActionParallel.Add(action2);
     listActionParallel.Add(action3);

     Parallel.Invoke(parallelOptions, listActionParallel.ToArray());
  }


=> After call ExecAutoCheck() method, 3 TestProject.exe will be executed parallel.
then these below files will be outputted with same content.
- FileNameTest1.txt
- FileNameTest2.txt
- FileNameTest3.txt
=> I try to run ExecAutoCheck() method about 5 times however result is the same.
With this test code i think that static variables are not shared memory between threads.
But I have not been found a clue to prove this.

I would be very grateful if someone explained this to me!!!

What I have tried:

Static variable will be stored in static area (static) similar to global variable.
In multi thread, i am understanding that static variables are being shared among threads.
However, with below code is seem that they are not shared.
So does that mean that on Managed C++ Multi thread will be different?
Posted
Updated 6-Apr-21 22:15pm
v2
Comments
Richard MacCutchan 7-Apr-21 3:27am    
You are not multithreading there, you are running three separate applications. Multiple threads run in a single address space.
alex giulio 7-Apr-21 7:13am    
Yes, i got it.
OriginalGriff helped me explain this question.
Thank you for your reply!!

1 solution

That's complicated. Yes, they are shared between threads - a static variable has one single instance for the whole life of the application - but that doesn't mean you can blindly change it's value in different thread simultaneously.

Think about it: in cmahine code terms, x++ is not a single operation - it's a form of "syntactic sugar" which expands several to lines of code:
C#
int y = x;
x = x + 1;
return y;
And if you have multiple threads executing that code at the same time, then some of them are going to get the wrong value, or return the wrong value because you have no control over which of those three lines any thread is executing at the same time.
The technical terms for this is that the operation is not thread safe.

So while static variables are "shared between threads" you have to be very careful what you do with them, or things get very unpredictable, very quickly.
Be aware that multithreading is not a simple magic bullet to fix performance problems: it needs to be thought about and planned massively in advance or it will give you more problems than it solves!

Have a look here: Managed Threading Best Practices | Microsoft Docs[^]
 
Share this answer
 
Comments
CPallini 7-Apr-21 2:07am    
5.
alex giulio 7-Apr-21 2:32am    
Thank you for the very quick reply!
According to your answer, they are sharing memory among threads, right?
So why is there no difference in the contents of the [FileNameTest1.txt, FileNameTest2.txt, FileNameTest3.txt] files as described?
OriginalGriff 7-Apr-21 4:12am    
Because you aren't multithreading - you are creating a new Process for each file - and separate processes do not share memory at all - each has it's own Heap, it's own stacks - so static variables are not shared either because they are not the same application even if they are execution the same instructions!

Think of it like a car: if you put your phone in the glove box of my car, do you expect to find it in the glove box of your car? Of course not! they are the same make, the same model, teh same colour, driving on the same road - but they are separate vehicles. Each car is a separate Process, and while the glove box of any car is available to all passengers in the car, it isn't shared between different instance of a car.

A process is not a thread, it is a thread (or more) plus the memory it needs.
alex giulio 7-Apr-21 4:27am    
I got it.
Thank you very much!!!
Issue solved well.
OriginalGriff 7-Apr-21 4:52am    
You're welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900