2
votes

If multiple threads are executing class procedure TDjelatBL.Test, is there going to be an exception due to accessing variable iPublic?

The point of my question is if accessing same variable/object/constant from two or more threads simultaneously will raise an exception. I assume that nature of change of variable/object does not change memory allocation like changing size of an array.

Closest question (comparing to this one) I have found is Is a Delphi global procedure threadsafe and Are Delphi simple types thread safe? but raising of an exception is never mentioned.

unit MTTest;

interface

uses
    System.SysUtils, System.Classes;

type

    TDjelatBL = class
    public
        class procedure Test;
    end;

var
    iPublic: Integer;
    StringList: TStringList;

implementation

class procedure TDjelatBL.Test;
var
    i: Integer;
begin
    StringList.Add('x');
    for i := 1 to 1000000000 do
    begin
        iPublic := iPublic + StringList.Count;
    end;
end;

initialization
    StringList := TStringList.Create;
finalization
    StringList.Free;
1
Possible duplicate of Are Delphi simple types thread safe?J...
tldr: No, it won't throw an exception but it won't necessarily work like you expect. You need to protect the variable with a critical section or some other synchronization method. Two threads can read the current value at the same time, both will add their counts to it, but only the last one to write will succeed in completing the add operation, for example. (Race condition)J...
Your example will generate an exception every single time 2 threads calls it at the same time, not because of iPublic, but because of StringList. It will at the very least crash on StringList.free, but more likely on StringList.Count, and possibly on StringList.Add as well.Ken Bourassa
Indeed - there's no reason to not make the stringlist a local variable.J...
It seems that you already tested it and got an exception. Did you tested the code? It raised any exception? What exception?EMBarbosa

1 Answers

3
votes

Simultaneous read/modify/write actions on an integer variable will not result in exceptions.

There is a classic data race condition with your code. But there will be no exception. Use InterlockedIncrement to avoid the data race.

Using a global variable for the string list is a problem. Expect exceptions when two threads try to use that single variable simultaneously. That variable should be a local variable, and then that particular problem is resolved.