Дженерики Delphi только для чтения, такие как TDictionary‹T› и TList‹T›, являются потокобезопасными?

Могу ли я добавлять элементы в общий список или словарь только при инициализации модуля, а затем использовать его как доступный только для чтения для нескольких потоков?

Я читал в теме, что TList<T> является потокобезопасным, а в другой теме, что TDictionary<T> - нет. Какая разница между ними?


person Paulo César Botelho Barbosa    schedule 12.08.2017    source источник
comment
Вы просматривали этот вопрос? stackoverflow.com/questions/27517063/   -  person John Easley    schedule 12.08.2017
comment
Большое спасибо за ответ. Я видел да, однако мой вопрос заключается в том, что если я инициализирую элементы словаря при инициализации некоторого модуля и использую его только для чтения в нескольких потоках, это безопасно.   -  person Paulo César Botelho Barbosa    schedule 12.08.2017


Ответы (1)


Чтение безопасно, Запись — нет. Пока вы можете гарантировать, что TList/TDictionary заполняется до того, как к нему будут обращаться какие-либо потоки, и вы только извлекаете элементы, никогда не добавляя/изменяя элементы, тогда это безопасно. Однако лучше не полагаться на такое поведение. Вы всегда должны явно синхронизировать доступ к общим ресурсам между потоками, например, с TCriticalSection, TMutex, TMREWSync (или блокировками Win32 SRW), TMonitor и т. д.

person Remy Lebeau    schedule 12.08.2017
comment
Если производительность имеет значение, вам следует избегать блокировок. Поэтому лучше полагаться на потокобезопасность только для чтения. - person David Heffernan; 12.08.2017
comment
@ Дэвид, не сказано, что какой-либо из них является потокобезопасным только для чтения. Это внутренняя реализация. Вы можете прочитать источник и сказать, что это так. Но однажды EMBT изменит реализацию, и вы удивитесь. - person Victoria; 13.08.2017
comment
@Victoria Это справедливо. Но в многопоточной среде, чувствительной к производительности, следует избегать блокировок, поэтому, если вы не можете доверять этим классам, вы должны реализовать свои собственные. - person David Heffernan; 13.08.2017
comment
@ Дэвид, я уже сделал это. Небезопасные потоки используют эффективные блокировки (тонкие RW или CS, если они есть, они узнают об этом :) Это легко, если вы разрешите им автообучение (что происходит во время компиляции и если разрешено во время выполнения), они проверка того, какие потоки делают. Если все они только читают и пока только один пытается записать, используется слим-блокировка RW. Если более чем один поток пытался писать, я обновляю блокировку до CS. - person Victoria; 13.08.2017
comment
@Victoria Это будет работать хуже, чем незащищенная коллекция, в этом сценарии только для чтения. - person David Heffernan; 13.08.2017
comment
@ Дэвид, ты имел в виду чем. Но, да, но это следствие неверия. Но я могу управлять им как во время компиляции, так и во время выполнения (варианты реализации потокового и небезопасного интерфейса словаря). - person Victoria; 13.08.2017
comment
@Victoria Я полагаю, я считаю, что Emba вообще не дает никаких гарантий потоковой передачи для любой из своих библиотек, поэтому вам как бы нужно полагаться на знание реализации. - person David Heffernan; 13.08.2017
comment
@ Дэвид, вот с чем я согласен. Как раз когда мы перешли с необобщенных коллекций на обобщённые, мы приняли это решение (чтобы сделать его для нас более явным). Теперь мы знаем, какой из наших пользовательских классов для какой цели создает экземпляр, с гарантией того, что он будет потокобезопасным или нет. Кстати. аналогичная ситуация, например, и в .NET. - person Victoria; 13.08.2017