-1

Hi In my multithreaded application some threads (and MainThread, ofcourse) are accessing to global string variable. Additional threads only read the value, but the main thread can change them. May be, i still need to use Synchronize?

Mr. David, what will tell You?

var
   maillist:tstringlist;
   mindex:integer; // global variables. 

procedure TMultiThread.Execute;
begin


  while true do
  begin
    if (icount>=0) or (terminated) then
    exit;
    try
      sec.enter; // critical section
      login := maillist.names[mIndex];
      UniqueString(login);
      password:=maillist.ValueFromIndex[mIndex];
      UniqueString(password);
      interlockedincrement(mindex);
    finally
      sec.leave;
    end;
    if terminated then exit;
    if (login=emptystr) or (password=emptystr) then
    continue;
The North Star
  • 104
  • 1
  • 10
  • Yes, you should still synchronize access. If the main thread changes the string while another thread is reading it, it may be reading in a piece of memory that is being reallocated by the main thread writing the string. I'd gladly try to give advice but it's not clear to me which variable you're talking about. – GolezTrol Nov 16 '15 at 19:01
  • Thanks, my friend ;) – The North Star Nov 16 '15 at 19:03

1 Answers1

1

For a complex object like a string, to avoid data corruption from race conditions, you need to synchronize access using a synchronization object. For instance:

  • TCriticalSection.
  • TMonitor.
  • TMultiReadExclusiveWriteSynchronizer.
  • Slim Reader/Writer (SRW) Locks.

Beyond just synchronizing to avoid data corruption you may need to synchronize for semantic correctness. It all depends on the way the data is used.

As a general rule, avoid sharing data where possible to avoid the need for synchronisation. Excessive synchronization hinders scalability.

This answer (https://stackoverflow.com/a/19703381/505088) shows how to make a generic threadsafe class, in this case using a critical section. You could use that idea with any of the synchronization objects above by making minimal changes.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • You wrote that when a string variable is available for the main thread and additional threads, it is a bad way to use a critical section only for additional threads, because the main thread may also refer to the variable. To put the same critical section in the main thread looks crazy. I don't know what to do... – The North Star Nov 16 '15 at 20:33
  • `Synchronize` forces code to run in the main thread. Critical sections are a mutual exclusion lock, and stop more than one thread entering the section simultaneously. You use or or other, but not both. In this case I see no reason to force onto main thread. Do bear in mind that we can only see a small portion of your code and so don't know your threading design. To be honest, it looks a little as though you are out of your depth and need to get a good book on this topic. – David Heffernan Nov 16 '15 at 20:37
  • Note that a critical section may have performance issues, if the class holding its buffer is smaller than the CPU cache line. See https://www.delphitools.info/2011/11/30/fixing-tcriticalsection/ – Arnaud Bouchez Nov 17 '15 at 09:04