|
|
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Есть поле класса Код: pascal 1. к нему идет обращение из разных потоков на чтение и запись. Нужна ли мне при этом синхронизация? Или когда я записываю новое значение в строку, Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после, С уважением, Vasilisk ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 17:56 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
12.08.2019 17:56, _Vasilisk_ пишет: > Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после, интересно послушать, что скажут монстры рока. раскапывать какая там неонка у неё внутре - долго и муторно. имхо, лучше перебдеть, чем недобдеть. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:12 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Нужна ли мне при этом синхронизация? Нужна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:13 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Kazantsev Alexey_Vasilisk_Нужна ли мне при этом синхронизация?Нужна.Тогда вопрос. Такой код Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. имеет право на существование? Или я должен писать так? Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. По идее без UniqueString синхронизация не имеет смысла ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:21 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:35 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
X-Cite, Это сейчас о чем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:39 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Или я должен писать так? Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. По идее без UniqueString синхронизация не имеет смысла Я всегда так пишу. Одной лишь CS недостаточно (вроде). В принципе, ошибки со строками довольно быстро отыскиваются, если сделать нагрузочный тест с несколькими потоками. Чем больше ядер у процессора, тем быстрее ошибка воспроизводится. От длины строки также может зависеть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:51 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Насколько я помню, только чтение синхронизировать не требуется (счётчик и так синхронизируется). Синхронизация нужна в сценариях где присутствует запись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 18:56 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Kazantsev Alexeyтолько чтение синхронизировать не требуется (счётчик и так синхронизируется). Синхронизация нужна в сценариях где присутствует запись.А какой смысл синхронизации записи при несинхронизированном чтении? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 19:00 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_А какой смысл синхронизации записи при несинхронизированном чтении? Kazantsev AlexeyСинхронизация нужна в сценариях где присутствует запись . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 19:08 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Вот, нашёл разъяснение от создателя: https://blog.therealoracleatdelphi.com/2015/11/friendly-reminder.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2019, 19:30 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Нужна ли мне при этом синхронизация? Или когда я записываю новое значение в строку, Delphi всегда выделяет новый кусок памяти и я никогда не прочитаю часть строки до присвоения и часть после Так со строками получиться не может благодаря copy-on-write, но синхронизация доступа к самой переменной таки нужна. Иначе, в отличии от случая с Integer кстати, геттер может получить из другого потока строку, которая будет вот-вот разрушена и дальнейшее обращение к этой переменной приведет к AV. UniqueString() не нужен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 00:48 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Синхронизация нужна, unique не нужен Можно заморочиться с лок фри, но это сложно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 06:18 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
UniqueString() не нужен Лучше пусть будет. Мы же не знаем, какая работа со строкой будет в дальнейшем. А cs больше не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 07:03 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Голландец_Vasilisk_, Синхронизация нужна, unique не нужен +1 по мне lock лучше для каждой несвязной переменной с контролем времени жизни свой сделать, по типу плюсов. например, Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. но мазохисты конечно встречаются везде... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 07:17 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Присвоение строк просто копирует указатель на один и тот же фрагмент памяти. Лок-анлок достаточно, если ты прям железно уверен, что сама строка не меняется. Но лучше добавить и копирование, если это не станет узким местом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 09:54 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Зачем копирование, если есть лок? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 10:48 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Может меняться содержимое строки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 12:05 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Логично же что может... Пока у вас обращение к переменной чтение/запись через блокировку то изменения строк управляемые.. Копирование тогда зачем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 12:16 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
X-CiteКопирование тогда зачем? Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlock ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 12:38 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
DmSerX-CiteКопирование тогда зачем? Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlock Вы не к строке обращаетесь, а к переменной. Выделите абстракцию (класс/ы), перенесите туда логику связанную со строкой.. в этой абстракции обеспечьте потокобезопасность и везде используйте ее.. Методы абстракции (классов) будут потокобезопасны, вызывайте где хотите... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 13:23 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
DmSerX-CiteКопирование тогда зачем? Чтобы не писать в дальнейшем при обращении к это строке Lock / Unlockа смысл? как уже написали выше, проблема при взятии строки увеличение инкремента может не успеть и строку удалят в другом потоке, по-этому операции с "хранилищем" надо лочить а дальше строка защищена механизмом CopyOnWrite, если напрямую не лезть в память, то проблем с копией строки нет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 13:54 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
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.08.2019, 14:30 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_ARGB32геттер может получить из другого потока строку, которая будет вот-вот разрушена и дальнейшее обращение к этой переменной приведет к AV.kealon(Ruslan)увеличение инкремента может не успеть и строку удалят в другом потоке, по-этому операции с "хранилищем" надо лочитьТакого быть не может. Изменение счетчика ссылок атомарная операция группа атомарных операций не атомарна Код: plaintext 1. 2. 3. т.е. при работе со строкой, interlocked функциями не обойтись ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:13 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)т.е. при работе со строкой, interlocked функциями не обойтисьОни там и есть Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:16 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. что будет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:19 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan) Код: plaintext 1. Это что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:21 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_там и есть Руки бы оторвать тому, что ЭТО написал... Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:29 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_если я Integer в одном потоке только читаю, а в другом только пишу, то и синхронизация мне не нужна. Мне не критично прочитать старое или новое значение Для Integer не нужна, но изменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памяти. Тест просто пишется, проверь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 16:12 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Kazantsev AlexeyМожет получится так, что прочитаешь указатель на освобождённый блок памяти. Это бы ещё ладно, а вот прочитать указатель на освобождённый и заново выделенный блок даст реально забавные спецэффекты и снос крыши при попытке отладки. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 16:20 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Kazantsev Alexeyизменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памятиТ.е. кроме лока нужна еще и UniqueString? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 17:25 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovРуки бы оторвать тому, что ЭТО написал...Что-то не вижу. В чем криминал? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 17:25 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Kazantsev Alexeyизменение строковой переменной, как уже сказали, операция не атомарная. Может получится так, что прочитаешь указатель на освобождённый блок памятиТ.е. кроме лока нужна еще и UniqueString?нет, если у тебя уже есть валидная строка, неважно сколько на неё "копий", работа с ней будет корректна _Vasilisk_Это что?копирование в регистр из участка памяти, куда идёт совместный доступ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 17:32 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Kazantsev AlexeyТ.е. кроме лока нужна еще и UniqueString? Нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 17:39 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_В чем криминал? Строка "if P.refCnt > 0 then" совершенно тут бесполезна и только вводит в заблуждение. К моменту её выполнения refCnt в многопоточном приложении должен быть либо больше единицы, либо приходит пушной зверёк. (Приложение в котором только один поток использует эту переменную считается за однопоточное.) Таким образом эта процедура построена на предположении, что вся остальная compiler magic работает корректно, а на уровне приложения обращение к переменной таки синхронизировано. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 17:41 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovСтрока "if P.refCnt > 0 then" совершенно тут бесполезна и только вводит в заблуждение. К моменту её выполнения refCnt в многопоточном приложении должен быть либо больше единицы, Нет. Для констант refCnt -1 и не изменяется Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 18:22 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Что-то я совсем потерялся. Давайте еще раз. string это указатель на структуру Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. codePage и elemSize модифицироваться не могут refCnt модифицируется атомарно length и data не модифицируются логикой программы. Новая строка только присваивается. Без всякого сложений и модификаций символов. Т.е. из всей структуры модифицируется только одно поле refCnt и то происходит атомарно. Зачем здесь синхронизация? Далее, допустим, синхронизация нужна, но не нужна UniqueString. Тогда я вообще не понимаю. Код _Vasilisk_ Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. по сути идентичен такому Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Но тогда любой код, вызвавший GetMessage получает тот же указатель, что и оригинальный FMessage, но уже ни о какой синхронизации не подозревает. Тогда в чем смысл был Lock/Unlock, если AddRef атомарна? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 18:39 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, потому что Код: pascal 1. это две операции: нужно сначала получить указатель на структура StrRec, а потом уже вызвать инкремент, и наоборот это принципиально не сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 18:43 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Для констант refCnt -1 и не изменяется Эва какие костыли... В любом случае, когда этот код параллельно выполняется для refCnt = 1, наступает "Бум!" поскольку один поток затормозил перед проверкой, второй в это время полностью выполнил процедуру и освободил память, первый прочухался и проверяет refCnt в уже освобождённом мусоре. А для глобальной переменной счётчик будет 1 без вариантов. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 18:55 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)это две операции: нужно сначала получить указатель на структура StrRec, а потом уже вызвать инкрементВсе. Уразумел. Извините за торможение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 19:33 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
Dimitry Sibiryakovпоскольку один поток затормозил перед проверкой, второй в это время полностью выполнил процедуру и освободил память,Нет. Декремент вызывается только при потере видимости. Если мы говорим о доступе к одной переменной из разных потоков, значит эта переменная не локальная, а, как минимум, поле класса. А значит видимость она потеряет только при вызове деструктора. Если же у нас два указателя на одну строку, то уже refCnt >= 2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 19:40 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_Dimitry Sibiryakovпоскольку один поток затормозил перед проверкой, второй в это время полностью выполнил процедуру и освободил память,Нет. Декремент вызывается только при потере видимости. Если мы говорим о доступе к одной переменной из разных потоков, значит эта переменная не локальная, а, как минимум, поле класса. А значит видимость она потеряет только при вызове деструктора. Если же у нас два указателя на одну строку, то уже refCnt >= 2 только читать наверное не особо интересно, надо наверное и писать - 21948221 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 23:57 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)только читать наверное не особо интересно, надо наверное и писать - 21948221 Так мы же договорились, что доступ к переменной только через синхронизацию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2019, 15:25 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_, Dimitry Sibiryakov тебе объяснял, что будет без лока ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2019, 16:08 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)Dimitry Sibiryakov тебе объяснял, что будет без локаДмитрий возмущался кривизной кода RTL. Я попросил показать в чем кривизна. Кроме того, обсуждаемый код RTL влияет на объекты "строка", а не на строковые переменные (которые указатели на эти объекты) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2019, 16:34 |
|
||
|
Синхронизация при доступе к строке
|
|||
|---|---|---|---|
|
#18+
_Vasilisk_обсуждаемый код RTL влияет на объекты "строка", а не на строковые переменные (которые указатели на эти объекты) Благодаря магии компилятора они "умные" указатели, что несколько изменяет картину. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2019, 16:44 |
|
||
|
|

start [/forum/topic.php?all=1&fid=58&tid=2039144]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
135ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
74ms |
get tp. blocked users: |
1ms |
| others: | 237ms |
| total: | 489ms |

| 0 / 0 |
