|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Имеется приложение в котором работают 3 потока - приложения и 2 дополнительных. Потоки читают одни и теже данные, включая данные, полученные другими потоками, но пишут в разные места, и, вроде, никакой конкуренции не было. Однако понадобилось, чтобы потоки обращались к одному и тому-же функционалу. Для определенности пусть это будет функция Код: c# 1. 2. 3. 4. 5. 6. 7.
Что будет если потоки обратятся к функции практически одновременно? Таким, например, образом 1-й - f(2,2,20), 2-й - f(3,3,10). 1. Все будет ОК, ведь обращаемся мы к Debug.WriteLine(""), и никаких конфликтов. 2. NET блокирует функцию до освобождения ресурсов и другому потоку придется подождать, и все опять ОК. 3. И тот и другой потоки получат и в итоге одинаковый ответ, например 6. В книжках днозначного ответа что-то не нашел - 50/50. "Есть многое на свете, друг Горацио, что и не сразу в голову придет." М. Твен "Приключения Геккельбери Финна" ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2014, 17:22 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAЧто будет если потоки обратятся к функции практически одновременно? Таким, например, образом 1-й - f(2,2,20), 2-й - f(3,3,10). 1ый уснет на 20мс и вернет 4, второй на 10 мс и вернет 6. С чего бы быть по-другому? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2014, 18:34 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA, В вашем случае, если работа будет идти только с параметрами, переданными в функцию, то никаких проблем не будет. Функция - это выделенный кусок исполнимого кода, и его синхронизировать с чем то не нужно абсолютно. Синхронизируют, при необходимости, только доступ к данным. Например, передающиеся по ссылке объекты. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2014, 18:37 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Arm79 , Если прав Pallaris , и на время выполнения функции, она блокируется Фреймвоком, то никаких проблем не должно быть. Однако, в одной из книг, в качестве примера, разбирался доступ к функции именно в таком ключе, что и в моем вопросе. [quote Arm79 ]Функция - это выделенный кусок исполнимого кода,[/quote] и ее экземпляр не создается при исполнении. Если поток заходит в функцию и присваивает a=2, b=2, после чего второй поток заходит в нее-же и присваивает тем-же ячейкам памяти a=3, b=3, то первая функция на выходе return a+b получит 6, а не 2+2=4. Arm79 Синхронизируют, при необходимости, только доступ к данным. Например, передающиеся по ссылке объекты. Доступ к функции, как правило, и есть доступ к объектам и получение ссылки на объект. И что там происходит в объекте, далеко не всегда очевидно. Хорошо пусть будут данные, пусть при обращении к функции объекта мы должны получить коллекцию строк (Rows), а другой поток одновременно хочет получить некую другую коллекцию. Хотелось бы подчеркнуть, что потоки пишут данные в разные места, и здесь четко разделены, а вот читают одни и те-же, либо данные других потоков, но чтение идет в разном контексте. Т.е. обращаясь к одним и тем-же функциям объектов делают разные вызовы. Хотелось бы, чтобы Pallaris был прав, но где это четко прочитать? Если возможно, цитату с ссылкой. К сожалению, в Инете ищется все хуже и хуже. :( ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2014, 22:24 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAчего второй поток заходит в нее-же и присваивает тем-же ячейкам памяти a=3, b=3 Осталось только понять, с чего вы взяли, что там те же ячейки? В вашем примере параметры метода - примитивные типы, следовательно, происходит передача по значению (а не по ссылке). Из чего следует, что каждый вызов метода приведет к копированию входных данных. То есть ячейки будут разными по любому. YUBAХотелось бы, чтобы Pallaris был прав Может, вы огорчитесь, но Pallaris прав. YUBAХотелось бы подчеркнуть, что потоки пишут данные в разные места, и здесь четко разделены, а вот читают одни и те-же, либо данные других потоков, но чтение идет в разном контексте. Т.е. обращаясь к одним и тем-же функциям объектов делают разные вызовы. Тут вообще ничего не понятно YUBAпусть при обращении к функции объекта мы должны получить коллекцию строк (Rows), а другой поток одновременно хочет получить некую другую коллекцию. А в чем вопрос то? Если функция создает в своем теле коллекцию строк (а не копирует откуда то), то эта коллекция никак не перемешается с другой ... |
|||
:
Нравится:
Не нравится:
|
|||
05.04.2014, 23:49 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA, YUBAК сожалению, в Инете ищется все хуже и хуже. :( гыгыгы Узбагойтесь, вернитесь к истокам : организация памяти, коль затронули функции - почитайте про стек вызовов (call stack) с такой кашей в голове дальше двигать нельзя (( ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 00:10 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Arm79, Читаем Рихтера "... Net via C#" РихтерВ то же время FCL не гарантирует безопасности в отношении потоков экземплярным методам, так как введение в них запирающего кода слишком сильно сказывается на производительности. Более того, если каждый экземплярный метод начнет выполнять запирание и отпирание, все закончится тем, что в приложении в каждый момент времени будет исполняться только один поток, что еще больше снизит производительность. Как уже упоминалось, поток, конструирующий объект, является единственным, кто имеет к нему доступ. Другим потокам данный объект недоступен, а значит, при вызове экземплярных методов синхронизация не требуется. с. 855 Эт хорошо, что прав. И скорее всего прав. Но понимания физики процесса нет. Но получается, что при обращении к функции объекта из потока, должна создаваться полная копия объекта содержащего эту функцию и взаимосвязанных объектов. Ведь она, функция, может содержать множество других функций как самого объекта, так и других объектов, а те в свою очередь... до бесконечности. Такое предположение - это дурдом. Вряд-ли это возможно. Если это не так, никакое копирование переменных в вызове функции не поможет, да и копируются они в функцию (точки входа). Что мешает их значения изменить другому потоку? Т.е., для нашего примера a и b должны поменяться на с 2, 2 на 3,3 при обращении из другого потока. Копирование же значений переменных в вызываемую функцию безопасно только для вызывающего объекта, для чего, собственно и сделано. Но никакой гарантии, что копии кто-то не изменит и функция будет работать нештатно. Но Вы сами писали Arm79Функция - это выделенный кусок исполнимого кода Т.е.. видимо, для всех потоков, это одни и те же ячейки памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 00:45 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Где-то в степи, я собственно и хочу разобраться. А про стек - каждый поток имеет свой стек. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 01:26 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
РихтерКогда поток конструирует новый объект при помощи оператора new, оператор возвращает ссылку на этот объект. Причем в этот момент ссылка имеется только у создающего объект потока, другие потоки не имеют к нему доступа. Если не передавать эту ссылку другому потоку, который может использовать объект одновременно с потоком, создавшим объект, необходимость в синхронизации отпадает. В моем случае все потоки работают с одними и теми же объектами и их методами. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 01:34 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA, в твоем случае - это в каком? В том примере, что ты привел, нет никаких объектов, и при вызове метода все переменные a,b,x,y,z для любого из потоков - уникальные (находятся в разных ячейках памяти в момент выполнения) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 09:41 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAЧитаем Рихтера "... Net via C#" В том куске, который вы привели, смысла мало. Очевидно, это вырванные их контекста фразы. YUBAпри обращении к функции объекта из потока, должна создаваться полная копия объекта содержащего эту функцию и взаимосвязанных объектов это неверная фраза. YUBAЕсли это не так, никакое копирование переменных в вызове функции не поможет, да и копируются они в функцию (точки входа) это тоже какая то фантастика. причем ненаучная :-) YUBAКопирование же значений переменных в вызываемую функцию безопасно только для вызывающего объекта, для чего, собственно и сделано. Но никакой гарантии, что копии кто-то не изменит и функция будет работать нештатно. Вам Где-то в степи подсказал почитать про стек вызовов. Жаль, вы не следуете хорошим советам. YUBAArm79Функция - это выделенный кусок исполнимого кода Т.е.. видимо, для всех потоков, это одни и те же ячейки памяти. У вас какое то катастрофическое непонимание. Функция - это исполнимый код. То есть инструкции процессора. Алгоритм. Если 10 участников работают по одному алгоритму, из этого не следует, что они должны работать поочередно. Они вполне могут и работать параллельно. Синхронизировать их работу нужно только в том случае, если все участники используют какие-то общие для всех вещи. Например, если вы сколачиваете табуретку, как и ваши соседи на уроке труда, то при наличии своих инструментов вы не обязаны оглядываться на них. Но если у вас один молоток на класс, вам придется волей-неволей как-то становиться в очередь к нему. Конечно, мое описание сильно уступает Рихтеру, да и по хорошему это абстракция, на которую накладываются физические ограничения памяти и процессора, но на вашем уровне это не важно пока что. ОС и компилятор скроют от вас такие "мелочи". Да, повторюсь. Ячейки памяти - это данные. Метод - это инструкции. Они к данным отношения не имеют. Теперь на примере кода. Этот код всегда будет выдавать одни и те же результаты при тех же входных данных при любом количестве потоков, в которых метод будет вызываться. Потому что в x и y передаются копии значений. И связи с оригиналом нет. Код: c# 1. 2. 3. 4. 5.
а вот этот код нельзя назвать потокобезопасным, потому что параметр p передает ссылку на объект. А сам объект может изменяться одновременно с этим методом и в других местах. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 11:35 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Вот если бы было Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Вот тогда бы начались проблемы при вызове из разных потоков Код: c# 1. 2.
т.к. переменные a и b будут общими для обоих потоков ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 11:41 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAих методами. А мне понятно, почему вы запутались. Слишком технически восприняли идею, что "методы находятся в классе". Значит типа надо создавать разные методы чтобы не пересекаться. Но тут классический обьектно ориентированный подоход "как бы" дает сбой - методы в процессе работы программы измениться не могут, и их сделали так, что физический код он один, а устроен так (с помощью стека и управления потоками) что может вызываться откуда угодно. Вы вобще знаете как работает процессор при переходе типа GOTO 555? Там есть регистр адреса, и вот при обычном проходе адрес просто увеличивается на единицу, а при прямом переходе - в регистр записывается 555 и следующая команда уже будет №555. То есть, по всей своей немаленькой памяти процессор перемещается мгновенно (за одну операцию). И это дает возможность свободно использовать общий участок кода (который где-то да, существует!) для всех экземпляров класса. А вот изменяемую часть - переменные, массивы переменных - это да, пишется в разное место для каждого нового экземпляра. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 12:25 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
PallarisВот если бы было Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Вот тогда бы начались проблемы при вызове из разных потоков Код: c# 1. 2.
т.к. переменные a и b будут общими для обоих потоков А именно так, собственно и есть. Но, думаю, и в моем варианте хорошо не закончится. Вечером проведу натурный эксперимент. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 13:03 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA А именно так, собственно и есть. Зачем тогда голову морочишь неправильными примерами? Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Вечером проведу натурный эксперимент. Удачи ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 13:06 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAВечером проведу натурный эксперимент. Проведите лучше мысленный. Если бы для разделения того, что функция делает, программисту на языке высокого уровня приходилось бы заморачиваться проблемами низкого уровня - то уже давно бы это изменили. И уже давно изменили. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 13:12 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
D129YUBAих методами.Вы вобще знаете как работает процессор при переходе типа GOTO 555? Там есть регистр адреса, и вот при обычном проходе адрес просто увеличивается на единицу, а при прямом переходе - в регистр записывается 555 и следующая команда уже будет №555. То есть, по всей своей немаленькой памяти процессор перемещается мгновенно (за одну операцию). И это дает возможность свободно использовать общий участок кода (который где-то да, существует!) для всех экземпляров класса. А вот изменяемую часть - переменные, массивы переменных - это да, пишется в разное место для каждого нового экземпляра.Вообще знаю, и как процессор, и что есть стек, и что туда пишется. А еще и вышивать умею, на ассемблере раньше приходилось, и в машинных кодах тоже. Именно, отталкиваясь от низкого уровня, все больше полагаю, что 2+2=6. Если в NET MS что-то не придумал. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 13:21 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA в NET MS что-то не придумал. С++ писал не микрософт. Понятие "класс" тоже не их. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 15:10 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBAВообще знаю, и как процессор, и что есть стек, и что туда пишется. не похоже ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 15:26 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA, авторА про стек - каждый поток имеет свой стек. == сахар белый проведите мысленный эксперимент: В стеке вызовов замените вызов функции inline встройкой в вышестоящий стек у вас че поток загнется? хотя компилятор это делает на ура и даже по принуждению (AggressiveInlining). или передайте тело как аргумент Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
тут никто не будет бить по рукам за это.. все Ваши фобии вызывают улыбку с ассоциацией юноши, который подрочив боится заразиться триппером )) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 16:32 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
Результаты натурного эксперимента. Код: c# 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. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58.
2+2=: Поток t1 3+3=: Поток t2 Задержка: 50 Задержка: 220 33 50 6 3+3=: 18 3+3=: Поток t2 Задержка: 50 33 50 6 3+3=: 18 3+3=: Поток t2 Задержка: 50 33 50 6 3+3=: 18 3+3=: Поток t2 Задержка: 50 33 50 6 3+3=: 18 3+3=: Поток t2 Задержка: 50 22 220 4 2+2=: 12 Поток '<Без имени>' (0xca4) завершился с кодом 0 (0x0). 33 50 6 3+3=: 18 Поток '<Без имени>' (0x1030) завершился с кодом 0 (0x0). Поток '<Без имени>' (0x1064) завершился с кодом 0 (0x0). Все, как видно, ОК. Каждый поток работает со своим образом функции. Тема исчерпана. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 16:58 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBA, YUBAсвоим образом функции Что такое "образ функции" ?) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 18:23 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
LelouchЧто такое "образ функции" ?)Образ - описание, модель, копия и т.д., достаточное, для полного восстановления объекта и его свойств. Как конкретно это реализовано MS не имеет значения. Да, Всем Спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 19:40 |
|
Многопоточность и разделяемые ресурсы.
|
|||
---|---|---|---|
#18+
YUBALelouchЧто такое "образ функции" ?)Образ - описание, модель, копия и т.д., достаточное, для полного восстановления объекта и его свойств. кто на ком стоял?(с) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.04.2014, 19:55 |
|
|
start [/forum/topic.php?fid=20&msg=38606520&tid=1403051]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
49ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 171ms |
0 / 0 |