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

Откуда: Украина, Харьков
Сообщений: 11292
Есть поле класса
FMessage: string

к нему идет обращение из разных потоков на чтение и запись.

Нужна ли мне при этом синхронизация? Или когда я записываю новое значение в строку, Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после,


С уважением, Vasilisk
12 авг 19, 17:56    [21947440]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 30662

12.08.2019 17:56, _Vasilisk_ пишет:
> Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после,

интересно послушать, что скажут монстры рока.

раскапывать какая там неонка у неё внутре - долго и муторно.
имхо, лучше перебдеть, чем недобдеть.

Posted via ActualForum NNTP Server 1.5

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

Откуда:
Сообщений: 3896
_Vasilisk_
Нужна ли мне при этом синхронизация?

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

Откуда: Украина, Харьков
Сообщений: 11292
Kazantsev Alexey
_Vasilisk_
Нужна ли мне при этом синхронизация?
Нужна.
Тогда вопрос. Такой код
function GetMessage: string;
begin
  Lock;
  try
    Result := FMessage;
  finally
    Unlock;
  end;
end;
имеет право на существование? Или я должен писать так?
function GetMessage: string;
begin
  Lock;
  try
    Result := FMessage;
    UniqueString(Result);
  finally
    Unlock;
  end;
end;

По идее без UniqueString синхронизация не имеет смысла
12 авг 19, 18:21    [21947460]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1609
function GetMessage: string;
begin
  Lock;
  try
    Result := FMessage;
  finally
    Unlock;
  end;
end;
12 авг 19, 18:35    [21947471]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11292
X-Cite,

Это сейчас о чем?
12 авг 19, 18:39    [21947473]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 926
_Vasilisk_
Или я должен писать так?
function GetMessage: string;
begin
  Lock;
  try
    Result := FMessage;
    UniqueString(Result);
  finally
    Unlock;
  end;
end;

По идее без UniqueString синхронизация не имеет смысла


Я всегда так пишу. Одной лишь CS недостаточно (вроде). В принципе, ошибки со строками довольно быстро отыскиваются, если сделать нагрузочный тест с несколькими потоками. Чем больше ядер у процессора, тем быстрее ошибка воспроизводится. От длины строки также может зависеть.
12 авг 19, 18:51    [21947479]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3896
_Vasilisk_,

Насколько я помню, только чтение синхронизировать не требуется (счётчик и так синхронизируется). Синхронизация нужна в сценариях где присутствует запись.
12 авг 19, 18:56    [21947480]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11292
Kazantsev Alexey
только чтение синхронизировать не требуется (счётчик и так синхронизируется). Синхронизация нужна в сценариях где присутствует запись.
А какой смысл синхронизации записи при несинхронизированном чтении?
12 авг 19, 19:00    [21947482]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 3896
_Vasilisk_
А какой смысл синхронизации записи при несинхронизированном чтении?


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

Откуда:
Сообщений: 3896
Вот, нашёл разъяснение от создателя: https://blog.therealoracleatdelphi.com/2015/11/friendly-reminder.html
12 авг 19, 19:30    [21947492]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
ARGB32
Member

Откуда: Мск
Сообщений: 37
_Vasilisk_
Нужна ли мне при этом синхронизация? Или когда я записываю новое значение в строку, Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после


Так со строками получиться не может благодаря copy-on-write, но синхронизация доступа к самой переменной таки нужна.
Иначе, в отличии от случая с Integer кстати, геттер может получить из другого потока строку, которая будет вот-вот разрушена и дальнейшее обращение к этой переменной приведет к AV.
UniqueString() не нужен.
13 авг 19, 00:48    [21947603]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Голландец
Member

Откуда:
Сообщений: 123
_Vasilisk_,

Синхронизация нужна, unique не нужен
Можно заморочиться с лок фри, но это сложно
13 авг 19, 06:18    [21947637]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 926
UniqueString() не нужен

Лучше пусть будет. Мы же не знаем, какая работа со строкой будет в дальнейшем. А cs больше не будет.
13 авг 19, 07:03    [21947640]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

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

Синхронизация нужна, unique не нужен
+1

по мне lock лучше для каждой несвязной переменной с контролем времени жизни свой сделать, по типу плюсов.
например,

TSync<t> = record
private
  l: TSpinLock;
  v: t;
  function GetValue(): t;
  procedure SetValue(const A: t);
public
  property Value read GetValue write SetValue;
end;


но мазохисты конечно встречаются везде...
13 авг 19, 07:17    [21947641]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Василий 2
Member

Откуда:
Сообщений: 815
Присвоение строк просто копирует указатель на один и тот же фрагмент памяти. Лок-анлок достаточно, если ты прям железно уверен, что сама строка не меняется. Но лучше добавить и копирование, если это не станет узким местом.
13 авг 19, 09:54    [21947720]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1609
Зачем копирование, если есть лок?
13 авг 19, 10:48    [21947778]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
Василий 2
Member

Откуда:
Сообщений: 815
Может меняться содержимое строки.
13 авг 19, 12:05    [21947904]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1609
Логично же что может...
Пока у вас обращение к переменной чтение/запись через блокировку то изменения строк управляемые..
Копирование тогда зачем?
13 авг 19, 12:16    [21947923]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 926
X-Cite
Копирование тогда зачем?


Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlock
13 авг 19, 12:38    [21947964]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1609
DmSer
X-Cite
Копирование тогда зачем?


Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlock

Вы не к строке обращаетесь, а к переменной.
Выделите абстракцию (класс/ы), перенесите туда логику связанную со строкой.. в этой абстракции обеспечьте потокобезопасность и везде используйте ее.. Методы абстракции (классов) будут потокобезопасны, вызывайте где хотите...
13 авг 19, 13:23    [21948033]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5359
DmSer
X-Cite
Копирование тогда зачем?


Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlock
а смысл?
как уже написали выше, проблема при взятии строки
увеличение инкремента может не успеть и строку удалят в другом потоке, по-этому операции с "хранилищем" надо лочить

а дальше строка защищена механизмом CopyOnWrite, если напрямую не лезть в память, то проблем с копией строки нет
13 авг 19, 13:54    [21948106]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11292
Kazantsev Alexey
Вот, нашёл разъяснение от создателя: https://blog.therealoracleatdelphi.com/2015/11/friendly-reminder.html
автор
Just like any other variable that is being read from or written to from many threads, string variables require the same level of protection as you would give to a simple Integer variable.
Так извини, меня, если я Integer в одном потоке только читаю, а в другом только пишу, то и синхронизация мне не нужна. Мне не критично прочитать старое или новое значение

ARGB32
геттер может получить из другого потока строку, которая будет вот-вот разрушена и дальнейшее обращение к этой переменной приведет к AV.
kealon(Ruslan)
увеличение инкремента может не успеть и строку удалят в другом потоке, по-этому операции с "хранилищем" надо лочить
Такого быть не может. Изменение счетчика ссылок атомарная операция
13 авг 19, 14:30    [21948152]     Ответить | Цитировать Сообщить модератору
 Re: Синхронизация при доступе к строке  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 5359
_Vasilisk_
ARGB32
геттер может получить из другого потока строку, которая будет вот-вот разрушена и дальнейшее обращение к этой переменной приведет к AV.
kealon(Ruslan)
увеличение инкремента может не успеть и строку удалят в другом потоке, по-этому операции с "хранилищем" надо лочить
Такого быть не может. Изменение счетчика ссылок атомарная операция
группа атомарных операций не атомарна

mov eax, [v]
<-  если здесь произведут декремент в другом потоке, то в eax будет ссылка на убитый кусок
call _straddref


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

Откуда: Украина, Харьков
Сообщений: 11292
kealon(Ruslan)
т.е. при работе со строкой, interlocked функциями не обойтись
Они там и есть
function _UStrClr(var S): Pointer;
var
  P: PStrRec;
begin
  if Pointer(S) <> nil then
  begin
    P := Pointer(PByte(S) - SizeOf(StrRec));
    Pointer(S) := nil;
    if P.refCnt > 0 then
    begin
      if AtomicDecrement(P.refCnt) = 0 then
        FreeMem(P);
    end;
  end;
  Result := @S;
end;
13 авг 19, 15:16    [21948216]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить