Re[9]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.04.23 20:24
Оценка: 92 (3)
Здравствуйте, Философ, Вы писали:

Ф>SpinLock не стоило относить к высокоуровневым.


Spin locks активно используются в ядрах ОС, в тех случаях, когда чисто технически невозможно выполнить ожидание с переключением контекста, а можно лишь поциклить какое-то разумное время (единицы-десятки микросекунд) в надежде, что параллельный, ядерный же, код, который не может быть прерван в любой момент на сколь угодно долгое время, быстро сделает свои дела и освободит блокировку. Если тщательно не следить за временем, проводимым в циклах, легко наплодить глюков — например, виндовые драйверы нередко проводят в ожидании сотни микросекунд, хотя положено не более 25.

Использовать такое на пользовательском уровне нужно с осторожностью, поскольку поток, вошедший в такой цикл, может быть прерван, и другой поток, пытающийся его дождаться, исчерпает свой квант, и тоже будет вытеснен. До какой-то частоты использования такие блокировки позволяют сэкономить на переключениях в ядро, но дальше они могут привести к резкому росту накладных расходов. Особенно в том случае, если код отлаживался на восьмиядерном процессоре, а затем запущен на двухъядерном, где вероятность прерывания потока примерно вчетверо выше.
Re[10]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 06.04.23 21:09
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Использовать такое на пользовательском уровне нужно с осторожностью, поскольку поток, вошедший в такой цикл, может быть прерван, и другой поток, пытающийся его дождаться, исчерпает свой квант, и тоже будет вытеснен. До какой-то частоты использования такие блокировки позволяют сэкономить на переключениях в ядро, но дальше они могут привести к резкому росту накладных расходов. Особенно в том случае, если код отлаживался на восьмиядерном процессоре, а затем запущен на двухъядерном, где вероятность прерывания потока примерно вчетверо выше.


Я знаю это. Спинлоки у меня там, где ожидаемое время WaitForSingleObject() на сигнальном объекте, например на свободном мьютексе, больше чем время ожидания. Второй случай, когда я такое использую — протокол реализован на MMF, где одно из полей — признак занятости. Там просто без вариантов: Sleep(1) ждёт дольше чем нужно.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[6]: Memory barrier не могу понять что это
От: Mr.Delphist  
Дата: 06.04.23 21:14
Оценка: 6 (1)
Здравствуйте, Sharowarsheg, Вы писали:

S>Ну да. Если ты намеренно не запрограммировал это на разных потоках, то барьер не нужен. Вообще, мне кажется, если программировать всё в одном потоке, то вообще можно не знать, что барьеры существуют. По крайней мере, в "обычных" языках и процессорах.


Безотносительно многопоточности, возможно переупорядочивание инструкций внутри одного ядра (АЛУ).

Погуглите
* cpu instruction reordering
* out of order execution

Если отдельно взятый поток/АЛУ решит, что заданные две инструкции можно исполнить в любом порядке (поскольку зависимостей между ними не наблюдает), то он выберет тот, который даст бОльшую эффективность по заданному policy: energy consumption, или memory throughput или idle cycle count, или что там сейчас считается важным.

Само собой, что возможны случаи, когда сделанное предположение об отсутствии зависимостей является неверным, и АЛУ тем самым вносит side-effect, который не ожидался автором программы — лезут плавающие баги. Особенно сложно правильно определять такие зависимости, когда имеем дело с managed-платформами, когда есть некоторый промежуточный уровень абстракции (рантайм C# или Java VM). Именно поэтому там вводится понятие "модели памяти" (memory model), чтобы хоть как-то очертить правила игры и дать базовые гарантии, работающие одинаково на всех поддерживаемых аппаратных платформах. Ну а если базовых гарантий недостаточно или мы хотим объехать их для какого-то выигрыша — тогда в бой идут явные задания барьеров памяти.
Re[4]: Memory barrier не могу понять что это
От: Mr.Delphist  
Дата: 06.04.23 21:26
Оценка: 6 (1) +2
Здравствуйте, vsb, Вы писали:

vsb>Ядра не знают про кеши других ядер. Существует некий протокол, который синхронизирует кеши, но это происходит как бы асинхронно. Процессор не ждёт окончания этой синхронизации для следующих операций. Он записал в кеш значение и потом специальное оборудование, которое управляет этим кешом, начинает рассылку сообщений по межпроцессорной шине, что по такому-то адресу значение поменялось. Эти сообщения через некоторое количество тактов достигнут другого ядра, другое ядро проверит, есть ли в его кеше такой адрес, если есть, то обновит в нём значение и так далее. То бишь если ты меняешь значение в памяти на одном процессоре, то другой процессор когда-нибудь его увидит. Но когда и в каком порядке — тут гарантий никаких без дополнительных инструкций не будет.


Однако определённый эффект на соседние ядра это тоже оказывает, поэтому, например, нельзя "бесплатно" (с точки зрения производительности) делать активную запись двумя потоками в две соседних ячейки памяти, если они попадают в одну кэш-линию. По каждому сигналу инвалидации кэш-линии, контроллер памяти будет ставить другое ядро на холд при попытке обращения к соседней ячейке, пока не синхронизирует два экземпляра этой кеш-линии. Хотя казалось бы, зачем тут синхронизация исполнения — ведь каждый поток пишет только в свою ячейку и никак не работает с соседней (гуглить false sharing).
Re[6]: Memory barrier не могу понять что это
От: okman Беларусь https://searchinform.ru/
Дата: 07.04.23 08:28
Оценка: 6 (1) +1
Здравствуйте, Философ, Вы писали:

Ф>Интересно, откуда инфа? Можно какие-нибудь доказательства [...] или дизасм получающегося кода, или объяснение того, что именно будет делать функция типа

Ф>
Ф>void Foo(){
Ф>Thread.MemoryBarrier();
Ф>}
Ф>


Ф>Я ОООчень бы хотел узнать, почему вы так думаете, откуда вы это взяли и где тут логика.

Ф>Т.е. если платформа не AMD64 будет действительно xchg. Но логики я тут всё равно не вижу.

Прежде всего, откуда я это взял. Работа такая
:-)


Да просто видел уже много-много раз при работе с крэш-дампами, в отладчике, в IDA Pro, при анализе ситуаций с зависаниями и другими проблемами.
Частенько приходится работать непосредственно с ассемблерными листингами, в основном это 32- и 64-битный код под архитектуры Intel/AMD (до ARM пока руки не дошли).
Также иногда интересно бывает написать что-то с использованием atomic или memory_order_xxx (C++) и посмотреть, во что компилятор превратит написанное.
И я вообще не припомню, чтобы хоть раз где-то видел sfence, lfence или mfence в многопоточке, в основном там всегда именно xchg, cmpxchg, xadd и т.п.

sfence/lfence/mfence, насколько я знаю, появились в SSE/SSE2 для поддержки non-temporal операций вроде movntdq, когда запись идет напрямую в память, не попадая в кэш CPU.
Т.е. они дают возможность упорядочивать такие операции более эффективным способом по сравнению с cpuid, например.

В обычном прикладном коде такие вещи практически не встречаются. Ну и сам по себе mfence, если верить дискуссиям в Гугле, занимает больше тактов CPU по сравнению с
locked-инструкциями типа xchg. Поэтому, а также ввиду определенных причин, связанных с особенностями работы Intel/AMD в этих аспектах, в "обычном" коде чаще
используется именно xchg, а не fence.

Вообще, тема эта очень обширная и сложная, в двух-трех предложениях и малой части не описать. Например, очень часто компилятор не вставляет никаких специальных
барьеров туда, где ты вроде бы их ожидаешь. Например потому, что определенные гарантии предоставляет сама архитектура: "stores are not reordered with other stores" и т.д.
Отредактировано 07.04.2023 8:33 okman . Предыдущая версия .
Re[7]: Memory barrier не могу понять что это
От: paradok  
Дата: 07.04.23 14:36
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:


MD>Само собой, что возможны случаи,


пример кода чтобы можно было запустить и увидеть эти самые плавающие ошибки?
Re[8]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 07.04.23 18:19
Оценка: 10 (1)
Здравствуйте, paradok, Вы писали:

MD>>Само собой, что возможны случаи,


P>пример кода чтобы можно было запустить и увидеть эти самые плавающие ошибки?


Можно. https://eric-lo.gitbook.io/lock-free-programming/memory-fence
Там в статье пример кода, который это демонстрирует.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 07.04.2023 18:20 Философ . Предыдущая версия .
Re[9]: Memory barrier не могу понять что это
От: 4058  
Дата: 08.04.23 06:17
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Здравствуйте, paradok, Вы писали:


P>>пример кода чтобы можно было запустить и увидеть эти самые плавающие ошибки?


Ф>Можно. https://eric-lo.gitbook.io/lock-free-programming/memory-fence

Ф>Там в статье пример кода, который это демонстрирует.

В данной статье автор в одном потоке пишет в глобальные переменные, а в другом из них читает без обеспечения должным образом критической секции при обращении к этим переменным (т.е. нарочито демонстрирует поведение ССЗБ):

, при этом настойчиво пытается продемонстрировать побочный эффект от переупорядочивания присвоений в обоих потоках разбросанных по разным ядрам.
Re[10]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 08.04.23 09:48
Оценка:
Здравствуйте, 4058, Вы писали:

4>В данной статье автор в одном потоке пишет в глобальные переменные, а в другом из них читает без обеспечения должным образом критической секции при обращении к этим переменным (т.е. нарочито демонстрирует поведение ССЗБ):..


В данной статье автор рассказывает о lock-free алгоритмах, поэтому там никаких локов быть в принципе не может.


4>, при этом настойчиво пытается продемонстрировать побочный эффект от переупорядочивания присвоений в обоих потоках разбросанных по разным ядрам.


Так ведь продемонстировал же! И демонстрашка там эта очень в тему: раз уж мы разбираемся в lock-free, то должны бы знать и о буферах переупорядочивания, и о спекулятивном исполнении и ещё много чего.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 08.04.2023 9:53 Философ . Предыдущая версия .
Re[5]: Memory barrier не могу понять что это
От: Pzz Россия https://github.com/alexpevzner
Дата: 08.04.23 14:45
Оценка: 6 (1) +2
Здравствуйте, okman, Вы писали:

O>sfence/lfence/mfence — это малость для другого. В машинный код для x86/x64 практически всегда вставляется инструкция типа xchg, xadd или что-то подобное.


Это разные вещи.

Представь, два потока на разных ядрах CPU у тебя одновременно инкрементируют одну переменную. Пусть даже с помощью одной инструкции процессора, а не трех (прочитать, проинкрементировать, сохранить).

Величина, на которую увеличится переменная, будет меньше, чем суммарное количество операций по ее увеличению, сделанных обеими потоками. Вот смотри, что делает инструкция INC, если ее аргумент — адрес в памяти, с учетом кеширования:
1. Загрузить значение в ALU. Значение само по себе, скорее всего, в кеше
2. Прибавить 1
3. Сохранить значение в кеш.

Поскольку потоков два, а переменная одна, на 3-м шаге возникает синхронизация кешей. На 3-м, заметь, а не на 1-м. Поэтому запросто может быть, что на первом шаге оба потока прочтут в ALU одно и то же значение (кеш в этот момент синхронен и процессору не о чем беспокоиться), прибавят к нему 1 и сохранят на место. Т.е., в итоге, переменная увеличится на 1, хотя оба потока ее увеличивали.

Чтобы этого избежать, существует префикс LOCK. Он делает всю цепочку 1-2-3 атомарной в том смысле, что с того момента, пока один поток сделал шаг 1 и до того, как он сделал 3, второму потоку просто не дадут туда войти.

У некоторых команд, типа XCHG, префикс LOCK встроенный, некоторым другим приходится приделывать его явно.

Это совсем не то же самое, что reordering инструкций, от которого "защищают" барьеры памяти.
Отредактировано 08.04.2023 18:38 Pzz . Предыдущая версия .
Re[6]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 08.04.23 22:08
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, okman, Вы писали:


Pzz>Чтобы этого избежать, существует префикс LOCK...

Pzz>Это совсем не то же самое, что reordering инструкций, от которого "защищают" барьеры памяти.

Ты не находишь странным такое объяснять системному программисту, который разбирает дампы и ковыряется в ассемблерных листингах!? По-моему он просто стебётся.
С другой стороны, он просто не понимает зачем вся эта фигня — просто никогда не слышал о lock-free алгоритмах. И при этом очень вероятно, что и не видел никогда в многопоточном коде *fence инструкций: lock-free всё-таки редкость. Даже сомневаюсь, что в ВУЗах такое учат.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[7]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 08.04.23 22:21
Оценка:
Здравствуйте, okman, Вы писали:

O>Да просто видел уже много-много раз при работе с крэш-дампами, в отладчике, в IDA Pro, при анализе ситуаций с зависаниями и другими проблемами.


Видел что? Во что превращается c++ intrinsic _mm_mfence?

O>И я вообще не припомню, чтобы хоть раз где-то видел sfence, lfence или mfence в многопоточке, в основном там всегда именно xchg, cmpxchg, xadd и т.п.


Это потому, что указанные инструкции используются для атомарных операций, при этом суть их — блокировки. Все приведённые инструкции неявно выставляют LOCK# на шину. Барьеры же используются для lock-free алгоритмов.

O>sfence/lfence/mfence, насколько я знаю, появились в SSE/SSE2 для поддержки non-temporal операций вроде movntdq, когда запись идет напрямую в память, не попадая в кэш CPU.


О таков варианте использования в мануале по оптимизации для Pentium-4, где они впервые появились. К несчастью полную докуменацию по Pentium-4 мне не удалось найти — не могу ни подтвердить, ни опровергнуть

O>В обычном прикладном коде такие вещи практически не встречаются. Ну и сам по себе mfence, если верить дискуссиям в Гугле, занимает больше тактов CPU по сравнению с

O>locked-инструкциями типа xchg.

Весьма примерно представляю, как это проверить. Буду рад примеру кода, который подтвердит или опровергнет эту гипотезу.

O>Вообще, тема эта очень обширная и сложная, в двух-трех предложениях и малой части не описать.


Ооо! Это точно.


O>Например, очень часто компилятор не вставляет никаких специальных

O>барьеров туда, где ты вроде бы их ожидаешь. Например потому, что определенные гарантии предоставляет сама архитектура: "stores are not reordered with other stores" и т.д.

Не понимаю о чём идёт речь. Что и где должно теоретически быть, но не вставляет? Я думал, что синхронизация целиком и полностью ответственность программиста.
Всё сказанное выше — личное мнение, если не указано обратное.
Отредактировано 08.04.2023 22:23 Философ . Предыдущая версия .
Re[7]: Memory barrier не могу понять что это
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 09.04.23 08:42
Оценка: 3 (1) +1
Здравствуйте, Философ, Вы писали:

Ф>С другой стороны, он просто не понимает зачем вся эта фигня — просто никогда не слышал о lock-free алгоритмах. И при этом очень вероятно, что и не видел никогда в многопоточном коде *fence инструкций


Или слышал и знает, что на x86/x64 атомарные операции создают full memory barrier...
Re[8]: Memory barrier не могу понять что это
От: okman Беларусь https://searchinform.ru/
Дата: 09.04.23 09:35
Оценка: 9 (1) +1
Здравствуйте, Философ, Вы писали:

Ф>Видел что? Во что превращается c++ intrinsic _mm_mfence?


Подчеркну: я описываю лишь то, что многократно видел сам за последние несколько лет. Без претензий на что-либо, просто наблюдения и выводы,
сделанные в контексте использования MS C++ под 32- и 64-битные версии Windows.

Если мы пишем 'MemoryBarrier' — компилятор впихнет туда xchg или какой-нибудь lock or.
Если используем Interlocked-функции или работаем через <atomic> из C++ (memory_order_seq_cst) — снова получаем на выходе xchg, cmpxchg, xadd и т.д.
Если заглянем в реализацию каких-нибудь примитивов синхронизации — там тоже много где используется "xchg и компания".
И т.д.

Почему там отсутствует (или исчезающе мало) mfence — я не берусь утверждать со 100% определенностью. Но подозреваю, что все очень прозаично и на
современных процессорах locked instructions вроде xchg выполняются быстрее, чем mfence.

Ну а sfence/lfence, если не рассматривать кейсы с "non-temporal hint", на x86 и x64 вообще бессмысленны, потому что там для "load-load" и
"store-store" порядок гарантируется архитектурой. И вставлять, например, sfence между двумя записывающими mov — только терять время.


Ф>Это потому, что указанные инструкции используются для атомарных операций, при этом суть их — блокировки. Все приведённые инструкции неявно выставляют LOCK# на шину. Барьеры же используются для lock-free алгоритмов.


Давайте рассмотрим xchg как пример. В контексте обсуждения эта инструкция обладает как минимум тремя полезными свойствами:

1. она атомарна
2. она работает как барьер, запрещая "перепрыгивать" через нее операциям записи или чтения
3. она сбрасывает буферы записи (store buffer), действуя аналогично инструкциям сериализации вроде cpuid

Пруф — документ "Intel® 64 and IA-32 Architectures Software Developer’s Manual (Combined Volumes)", редакция "May 2019":

8.2.2 Memory Ordering in P6 and More Recent Processor Families

...
Reads or writes cannot be reordered with I/O instructions, locked instructions, or serializing instructions.
...
Locked instructions have a total order.


11.10 STORE BUFFER

Intel 64 and IA-32 processors temporarily store each write (store) to memory in a store buffer. The store buffer
improves processor performance by allowing the processor to continue executing instructions without having to
wait until a write to memory and/or to a cache is complete. It also allows writes to be delayed for more efficient use
of memory-access bus cycles.

In general, the existence of the store buffer is transparent to software, even in systems that use multiple processors.
The processor ensures that write operations are always carried out in program order. It also insures that the
contents of the store buffer are always drained to memory in the following situations:

...

* When a LOCK operation is performed.

...


22.34 STORE BUFFERS AND MEMORY ORDERING

The Pentium 4, Intel Xeon, and P6 family processors provide a store buffer for temporary storage of writes (stores)
to memory (see Section 11.10, “Store Buffer”). Writes stored in the store buffer(s) are always written to memory
in program order, with the exception of “fast string” store operations (see Section 8.2.4, “Fast-String Operation and
Out-of-Order Stores”).

The Pentium processor has two store buffers, one corresponding to each of the pipelines. Writes in these buffers
are always written to memory in the order they were generated by the processor core.

It should be noted that only memory writes are buffered and I/O writes are not. The Pentium 4, Intel Xeon, P6
family, Pentium, and Intel486 processors do not synchronize the completion of memory writes on the bus and
instruction execution after a write. An I/O, locked, or serializing instruction needs to be executed to synchronize
writes with the next instruction (see Section 8.3, “Serializing Instructions”).


И теперь вопрос от меня: чем xchg хуже mfence в плане использования в качестве барьера?


O>>В обычном прикладном коде такие вещи практически не встречаются. Ну и сам по себе mfence, если верить дискуссиям в Гугле, занимает больше тактов CPU по сравнению с

O>>locked-инструкциями типа xchg.

Ф>Весьма примерно представляю, как это проверить. Буду рад примеру кода, который подтвердит или опровергнет эту гипотезу.


У меня есть только ссылка, ведущая на обсуждение в группы linux kernel, где, насколько я понял, там в итоге отказались от mfence в пользу lock:

x86 memory barrier: why does Linux prefer MFENCE to Locked ADD?
https://groups.google.com/g/fa.linux.kernel/c/hNOoIZc6I9E/m/WlyXcgwoCwAJ


O>>Например, очень часто компилятор не вставляет никаких специальных

O>>барьеров туда, где ты вроде бы их ожидаешь. Например потому, что определенные гарантии предоставляет сама архитектура: "stores are not reordered with other stores" и т.д.

Ф>Не понимаю о чём идёт речь. Что и где должно теоретически быть, но не вставляет? Я думал, что синхронизация целиком и полностью ответственность программиста.


Ну например, примерно такой код обычно приводится в качестве примера использования acquire/release семантики:
#include <atomic>
#include <cstdio>
#include <thread>
 
int data;
std::atomic<bool> ready;
 
void producer()
{
    data = 123;
    ready.store(true, std::memory_order_release);
}
 
void consumer()
{
    while (false == ready.load(std::memory_order_acquire)) {}
    printf("data = %d", data);
}
 
int main()
{
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join(); t2.join();
    return 0;
}


Здесь, мол, у нас в producer между записью в data и ready будет барьер, гарантирующий, что первое будет завершено строго до второго. И то же самое в consumer —
поток сначала увидит ready, и только потом начнет читать data. Но если посмотреть сгенерированный ассемблерный код, там нет никаких явно выставленных барьеров
при работе с переменной 'ready', просто mov на чтение и mov на запись:
void producer(void) PROC
    mov     DWORD PTR int data, 123
    npad    1
    mov     BYTE PTR std::atomic<bool> ready, 1
    ret     0
void producer(void) ENDP 

void consumer(void) PROC
    npad    2
$LL2@consumer:
    movzx   eax, BYTE PTR std::atomic<bool> ready
    npad    1
    test    al, al
    je      SHORT $LL2@consumer
    ...
void consumer(void) ENDP
Re[8]: Memory barrier не могу понять что это
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 09.04.23 10:52
Оценка: +1
Здравствуйте, Философ, Вы писали:

Ф>Это потому, что указанные инструкции используются для атомарных операций, при этом суть их — блокировки. Все приведённые инструкции неявно выставляют LOCK# на шину. Барьеры же используются для lock-free алгоритмов.


Я что-то думал, что lock-free алгоритмы — это про то, что не используется никаких объектов синхронизации, даже таких легких, как spin lock/CriticalSection. Без атомарных операций lock-free вряд ли получиться сделать, и префикс команды LOCK он не про то совсем
Маньяк Робокряк колесит по городу
Re[9]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 09.04.23 12:11
Оценка:
Здравствуйте, okman, Вы писали:

O>2. она работает как барьер, запрещая "перепрыгивать" через нее операциям записи или чтения

O>3. она сбрасывает буферы записи (store buffer), действуя аналогично инструкциям сериализации вроде cpuid

O>

O>8.2.2 Memory Ordering in P6 and More Recent Processor Families
O>Locked instructions have a total order.


O>

O> * When a LOCK operation is performed.

O> ...



Спасибо. Это то, что я упустил — забыл, или не внимательно читал. Я аж полез и перепроверил — это действительно так.
Сорри, просто не знал, об эффектах префикса LOCK.

O>И теперь вопрос от меня: чем xchg хуже mfence в плане использования в качестве барьера?


Не знаю.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[8]: Memory barrier не могу понять что это
От: Философ Ад http://vk.com/id10256428
Дата: 09.04.23 12:12
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Или слышал и знает, что на x86/x64 атомарные операции создают full memory barrier...


Полагаю, что тут этого много кто не знал. Я проверил — это действительно так.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[5]: Memory barrier не могу понять что это
От: vmpire Россия  
Дата: 09.04.23 20:08
Оценка: 6 (1)
Здравствуйте, Sharov, Вы писали:


vsb>>Могут быть и более тонкие баги, к примеру конструктор вызывается в одном потоке, указатель на сконструированный объект передаётся в другой поток, но другой поток видит не до конца сконструированный объект и будут очень странные баги. В Java в конструкторы специально вставляются нужные барьеры, чтобы такой ситуации не возникло, про C# не знаю. В С++ такое точно возможно.


S>Ага, в шарпе все также как и в Яве. Т.е. нельзя "опубликовать" не до конца сконтруированный объект.

А если в середине конструктора вызвать виртуальный метод, который передаст this в другой поток?
Re[6]: Memory barrier не могу понять что это
От: Sharov Россия  
Дата: 09.04.23 21:50
Оценка:
Здравствуйте, vmpire, Вы писали:

S>>Ага, в шарпе все также как и в Яве. Т.е. нельзя "опубликовать" не до конца сконтруированный объект.

V>А если в середине конструктора вызвать виртуальный метод, который передаст this в другой поток?

Интересно, не пробовал. Зачем для этого виртуальный метод, любой пойдет же?
Кодом людям нужно помогать!
Re[7]: Memory barrier не могу понять что это
От: vmpire Россия  
Дата: 10.04.23 00:23
Оценка:
Здравствуйте, Sharov, Вы писали:


S>>>Ага, в шарпе все также как и в Яве. Т.е. нельзя "опубликовать" не до конца сконтруированный объект.

V>>А если в середине конструктора вызвать виртуальный метод, который передаст this в другой поток?
S>Интересно, не пробовал. Зачем для этого виртуальный метод, любой пойдет же?
Виртуальный интереснее. Так может быть ещё не до конца инициализирован даже базовый класс
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.