Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 4982
_Vasilisk_,

thred1:
mov eax, [v]

thred2:
 _UStrClr [v]

thred1:
call _straddref


что будет?
13 авг 19, 15:19    [21948221]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
kealon(Ruslan)
mov eax, [v]
Это что?
13 авг 19, 15:21    [21948224]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47967

_Vasilisk_
там и есть

Руки бы оторвать тому, что ЭТО написал...

Posted via ActualForum NNTP Server 1.5

13 авг 19, 15:29    [21948242]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3625
_Vasilisk_
если я Integer в одном потоке только читаю, а в другом только пишу, то и синхронизация мне не нужна. Мне не критично прочитать старое или новое значение

Для Integer не нужна, но изменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памяти. Тест просто пишется, проверь.
13 авг 19, 16:12    [21948290]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47967

Kazantsev Alexey
Может получится так, что прочитаешь указатель на освобождённый блок памяти.

Это бы ещё ладно, а вот прочитать указатель на освобождённый и заново выделенный блок даст
реально забавные спецэффекты и снос крыши при попытке отладки.

Posted via ActualForum NNTP Server 1.5

13 авг 19, 16:20    [21948303]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
Kazantsev Alexey
изменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памяти
Т.е. кроме лока нужна еще и UniqueString?
13 авг 19, 17:25    [21948419]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
Dimitry Sibiryakov
Руки бы оторвать тому, что ЭТО написал...
Что-то не вижу. В чем криминал?
13 авг 19, 17:25    [21948421]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 4982
_Vasilisk_
Kazantsev Alexey
изменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памяти
Т.е. кроме лока нужна еще и UniqueString?
нет, если у тебя уже есть валидная строка, неважно сколько на неё "копий", работа с ней будет корректна


_Vasilisk_
Это что?
копирование в регистр из участка памяти, куда идёт совместный доступ
13 авг 19, 17:32    [21948435]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3625
_Vasilisk_
Kazantsev Alexey
Т.е. кроме лока нужна еще и UniqueString?

Нет.
13 авг 19, 17:39    [21948440]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47967

_Vasilisk_
В чем криминал?

Строка "if P.refCnt > 0 then" совершенно тут бесполезна и только вводит в заблуждение. К
моменту её выполнения refCnt в многопоточном приложении должен быть либо больше единицы,
либо приходит пушной зверёк. (Приложение в котором только один поток использует эту
переменную считается за однопоточное.)

Таким образом эта процедура построена на предположении, что вся остальная compiler magic
работает корректно, а на уровне приложения обращение к переменной таки синхронизировано.

Posted via ActualForum NNTP Server 1.5

13 авг 19, 17:41    [21948445]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
Dimitry Sibiryakov
Строка "if P.refCnt > 0 then" совершенно тут бесполезна и только вводит в заблуждение. К моменту её выполнения refCnt в многопоточном приложении должен быть либо больше единицы,
Нет. Для констант refCnt -1 и не изменяется
procedure _UStrAsg(var Dest: UnicodeString; const Source: UnicodeString); // globals (need copy)
{$IFDEF PUREPASCAL}
var
  S, D: Pointer;
  P: PStrRec;
  Len: LongInt;
begin
  S := Pointer(Source);
  if S <> nil then
  begin
    if __StringRefCnt(Source) < 0 then   // make copy of string literal
    begin
      Len := __StringLength(Source);
      S := _NewUnicodeString(Len);
      Move(Pointer(Source)^, S^, Len * SizeOf(WideChar));
    end else
    begin
      P := PStrRec(PByte(S) - SizeOf(StrRec));
      AtomicIncrement(P.refCnt);
    end;
  end;
  D := Pointer(Dest);
  Pointer(Dest) := S;
  _UStrClr(D);
end;
13 авг 19, 18:22    [21948476]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
Что-то я совсем потерялся. Давайте еще раз. string это указатель на структуру
  StrRec = packed record
  {$IF defined(CPUX64)}
    _Padding: LongInt; // Make 16 byte align for payload..
  {$ENDIF}
    codePage: Word;
    elemSize: Word;
    refCnt: Longint;
    length: Longint;
    data: array[0...] of Char;
  end;
codePage и elemSize модифицироваться не могут refCnt модифицируется атомарно length и data не модифицируются логикой программы. Новая строка только присваивается. Без всякого сложений и модификаций символов.

Т.е. из всей структуры модифицируется только одно поле refCnt и то происходит атомарно. Зачем здесь синхронизация?

Далее, допустим, синхронизация нужна, но не нужна UniqueString. Тогда я вообще не понимаю. Код
_Vasilisk_
function GetMessage: string;
begin
  Lock;
  try
    Result := FMessage;
  finally
    Unlock;
  end;
end;
по сути идентичен такому
FMessage: Pointer;
....
function GetMessage: Pointer;
begin
  Lock;
  try
    AddRef(FMessage)
    Result := FMessage;
  finally
    Unlock;
  end;
end;
Но тогда любой код, вызвавший GetMessage получает тот же указатель, что и оригинальный FMessage, но уже ни о какой синхронизации не подозревает. Тогда в чем смысл был Lock/Unlock, если AddRef атомарна?
13 авг 19, 18:39    [21948486]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 4982
_Vasilisk_,

потому что

Result := FMessage;
это две операции: нужно сначала получить указатель на структура StrRec, а потом уже вызвать инкремент, и наоборот это принципиально не сделать
13 авг 19, 18:43    [21948489]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47967

_Vasilisk_
Для констант refCnt -1 и не изменяется

Эва какие костыли...

В любом случае, когда этот код параллельно выполняется для refCnt = 1, наступает "Бум!"
поскольку один поток затормозил перед проверкой, второй в это время полностью выполнил
процедуру и освободил память, первый прочухался и проверяет refCnt в уже освобождённом
мусоре. А для глобальной переменной счётчик будет 1 без вариантов.

Posted via ActualForum NNTP Server 1.5

13 авг 19, 18:55    [21948497]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
kealon(Ruslan)
это две операции: нужно сначала получить указатель на структура StrRec, а потом уже вызвать инкремент
Все. Уразумел. Извините за торможение
13 авг 19, 19:33    [21948532]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
Dimitry Sibiryakov
поскольку один поток затормозил перед проверкой, второй в это время полностью выполнил процедуру и освободил память,
Нет. Декремент вызывается только при потере видимости. Если мы говорим о доступе к одной переменной из разных потоков, значит эта переменная не локальная, а, как минимум, поле класса. А значит видимость она потеряет только при вызове деструктора.

Если же у нас два указателя на одну строку, то уже refCnt >= 2
13 авг 19, 19:40    [21948534]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 4982
_Vasilisk_
Dimitry Sibiryakov
поскольку один поток затормозил перед проверкой, второй в это время полностью выполнил процедуру и освободил память,
Нет. Декремент вызывается только при потере видимости. Если мы говорим о доступе к одной переменной из разных потоков, значит эта переменная не локальная, а, как минимум, поле класса. А значит видимость она потеряет только при вызове деструктора.

Если же у нас два указателя на одну строку, то уже refCnt >= 2
только читать наверное не особо интересно, надо наверное и писать - 21948221
13 авг 19, 23:57    [21948714]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
kealon(Ruslan)
только читать наверное не особо интересно, надо наверное и писать - 21948221
Так мы же договорились, что доступ к переменной только через синхронизацию
14 авг 19, 15:25    [21949359]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 4982
_Vasilisk_,

Dimitry Sibiryakov тебе объяснял, что будет без лока
14 авг 19, 16:08    [21949399]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11090
kealon(Ruslan)
Dimitry Sibiryakov тебе объяснял, что будет без лока
Дмитрий возмущался кривизной кода RTL. Я попросил показать в чем кривизна.

Кроме того, обсуждаемый код RTL влияет на объекты "строка", а не на строковые переменные (которые указатели на эти объекты)
14 авг 19, 16:34    [21949434]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47967

_Vasilisk_
обсуждаемый код RTL влияет на объекты "строка", а не на строковые переменные (которые
указатели на эти объекты)

Благодаря магии компилятора они "умные" указатели, что несколько изменяет картину.

Posted via ActualForum NNTP Server 1.5

14 авг 19, 16:44    [21949444]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить