powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Многопоточность и разделяемые ресурсы.
25 сообщений из 72, страница 1 из 3
Многопоточность и разделяемые ресурсы.
    #38606144
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется приложение в котором работают 3 потока - приложения и 2 дополнительных. Потоки читают одни и теже данные, включая данные, полученные другими потоками, но пишут в разные места, и, вроде, никакой конкуренции не было. Однако понадобилось, чтобы потоки обращались к одному и тому-же функционалу. Для определенности пусть это будет функция
Код: c#
1.
2.
3.
4.
5.
6.
7.
double f(double x, double y, int z)
{
double a,b;
a=x; b=y;
Thread.Sleep(z); //типа что-то делаем
return a+b;
}


Что будет если потоки обратятся к функции практически одновременно? Таким, например, образом 1-й - f(2,2,20), 2-й - f(3,3,10).

1. Все будет ОК, ведь обращаемся мы к Debug.WriteLine(""), и никаких конфликтов.
2. NET блокирует функцию до освобождения ресурсов и другому потоку придется подождать, и все опять ОК.
3. И тот и другой потоки получат и в итоге одинаковый ответ, например 6.

В книжках днозначного ответа что-то не нашел - 50/50.


"Есть многое на свете, друг Горацио, что и не сразу в голову придет."
М. Твен "Приключения Геккельбери Финна"
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606170
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAЧто будет если потоки обратятся к функции практически одновременно? Таким, например, образом 1-й - f(2,2,20), 2-й - f(3,3,10).


1ый уснет на 20мс и вернет 4, второй на 10 мс и вернет 6. С чего бы быть по-другому?
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606173
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA,

В вашем случае, если работа будет идти только с параметрами, переданными в функцию, то никаких проблем не будет. Функция - это выделенный кусок исполнимого кода, и его синхронизировать с чем то не нужно абсолютно. Синхронизируют, при необходимости, только доступ к данным. Например, передающиеся по ссылке объекты.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606218
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79 , Если прав Pallaris , и на время выполнения функции, она блокируется Фреймвоком, то никаких проблем не должно быть.
Однако, в одной из книг, в качестве примера, разбирался доступ к функции именно в таком ключе, что и в моем вопросе.
[quote Arm79 ]Функция - это выделенный кусок исполнимого кода,[/quote] и ее экземпляр не создается при исполнении. Если поток заходит в функцию и присваивает a=2, b=2, после чего второй поток заходит в нее-же и присваивает тем-же ячейкам памяти a=3, b=3, то первая функция на выходе return a+b получит 6, а не 2+2=4.
Arm79 Синхронизируют, при необходимости, только доступ к данным. Например, передающиеся по ссылке объекты.
Доступ к функции, как правило, и есть доступ к объектам и получение ссылки на объект. И что там происходит в объекте, далеко не всегда очевидно.
Хорошо пусть будут данные, пусть при обращении к функции объекта мы должны получить коллекцию строк (Rows), а другой поток одновременно хочет получить некую другую коллекцию.
Хотелось бы подчеркнуть, что потоки пишут данные в разные места, и здесь четко разделены, а вот читают одни и те-же, либо данные других потоков, но чтение идет в разном контексте. Т.е. обращаясь к одним и тем-же функциям объектов делают разные вызовы.
Хотелось бы, чтобы Pallaris был прав, но где это четко прочитать?
Если возможно, цитату с ссылкой. К сожалению, в Инете ищется все хуже и хуже. :(
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606248
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAчего второй поток заходит в нее-же и присваивает тем-же ячейкам памяти a=3, b=3
Осталось только понять, с чего вы взяли, что там те же ячейки? В вашем примере параметры метода - примитивные типы, следовательно, происходит передача по значению (а не по ссылке). Из чего следует, что каждый вызов метода приведет к копированию входных данных. То есть ячейки будут разными по любому.

YUBAХотелось бы, чтобы Pallaris был прав
Может, вы огорчитесь, но Pallaris прав.

YUBAХотелось бы подчеркнуть, что потоки пишут данные в разные места, и здесь четко разделены, а вот читают одни и те-же, либо данные других потоков, но чтение идет в разном контексте. Т.е. обращаясь к одним и тем-же функциям объектов делают разные вызовы.
Тут вообще ничего не понятно


YUBAпусть при обращении к функции объекта мы должны получить коллекцию строк (Rows), а другой поток одновременно хочет получить некую другую коллекцию.
А в чем вопрос то? Если функция создает в своем теле коллекцию строк (а не копирует откуда то), то эта коллекция никак не перемешается с другой
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606251
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA,
YUBAК сожалению, в Инете ищется все хуже и хуже. :( гыгыгы
Узбагойтесь, вернитесь к истокам : организация памяти, коль затронули функции - почитайте про стек вызовов (call stack)
с такой кашей в голове дальше двигать нельзя ((
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606255
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79,
Читаем Рихтера "... Net via C#"
РихтерВ то же время FCL не гарантирует безопасности в отношении потоков
экземплярным методам, так как введение в них запирающего кода слишком
сильно сказывается на производительности. Более того, если каждый экземплярный
метод начнет выполнять запирание и отпирание, все закончится тем,
что в приложении в каждый момент времени будет исполняться только один
поток, что еще больше снизит производительность. Как уже упоминалось, поток,
конструирующий объект, является единственным, кто имеет к нему доступ.
Другим потокам данный объект недоступен, а значит, при вызове экземплярных
методов синхронизация не требуется. с. 855
Эт хорошо, что прав. И скорее всего прав. Но понимания физики процесса нет.
Но получается, что при обращении к функции объекта из потока, должна создаваться полная копия объекта содержащего эту функцию и взаимосвязанных объектов. Ведь она, функция, может содержать множество других функций как самого объекта, так и других объектов, а те в свою очередь... до бесконечности. Такое предположение - это дурдом. Вряд-ли это возможно.
Если это не так, никакое копирование переменных в вызове функции не поможет, да и копируются они в функцию (точки входа). Что мешает их значения изменить другому потоку? Т.е., для нашего примера a и b должны поменяться на с 2, 2 на 3,3 при обращении из другого потока.
Копирование же значений переменных в вызываемую функцию безопасно только для вызывающего объекта, для чего, собственно и сделано. Но никакой гарантии, что копии кто-то не изменит и функция будет работать нештатно.
Но Вы сами писали Arm79Функция - это выделенный кусок исполнимого кода Т.е.. видимо, для всех потоков, это одни и те же ячейки памяти.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606261
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степи, я собственно и хочу разобраться.
А про стек - каждый поток имеет свой стек.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606262
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
РихтерКогда
поток конструирует новый объект при помощи оператора new, оператор возвращает
ссылку на этот объект. Причем в этот момент ссылка имеется только у создающего
объект потока, другие потоки не имеют к нему доступа. Если не передавать
эту ссылку другому потоку, который может использовать объект одновременно
с потоком, создавшим объект, необходимость в синхронизации отпадает.
В моем случае все потоки работают с одними и теми же объектами и их методами.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606315
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA,

в твоем случае - это в каком? В том примере, что ты привел, нет никаких объектов, и при вызове метода все переменные a,b,x,y,z для любого из потоков - уникальные (находятся в разных ячейках памяти в момент выполнения)
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606354
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAЧитаем Рихтера "... Net via C#"
В том куске, который вы привели, смысла мало. Очевидно, это вырванные их контекста фразы.
YUBAпри обращении к функции объекта из потока, должна создаваться полная копия объекта содержащего эту функцию и взаимосвязанных объектов
это неверная фраза.
YUBAЕсли это не так, никакое копирование переменных в вызове функции не поможет, да и копируются они в функцию (точки входа)
это тоже какая то фантастика. причем ненаучная :-)
YUBAКопирование же значений переменных в вызываемую функцию безопасно только для вызывающего объекта, для чего, собственно и сделано. Но никакой гарантии, что копии кто-то не изменит и функция будет работать нештатно.
Вам Где-то в степи подсказал почитать про стек вызовов. Жаль, вы не следуете хорошим советам.
YUBAArm79Функция - это выделенный кусок исполнимого кода Т.е.. видимо, для всех потоков, это одни и те же ячейки памяти.
У вас какое то катастрофическое непонимание. Функция - это исполнимый код. То есть инструкции процессора. Алгоритм. Если 10 участников работают по одному алгоритму, из этого не следует, что они должны работать поочередно. Они вполне могут и работать параллельно. Синхронизировать их работу нужно только в том случае, если все участники используют какие-то общие для всех вещи. Например, если вы сколачиваете табуретку, как и ваши соседи на уроке труда, то при наличии своих инструментов вы не обязаны оглядываться на них. Но если у вас один молоток на класс, вам придется волей-неволей как-то становиться в очередь к нему.

Конечно, мое описание сильно уступает Рихтеру, да и по хорошему это абстракция, на которую накладываются физические ограничения памяти и процессора, но на вашем уровне это не важно пока что. ОС и компилятор скроют от вас такие "мелочи".

Да, повторюсь. Ячейки памяти - это данные. Метод - это инструкции. Они к данным отношения не имеют.




Теперь на примере кода. Этот код всегда будет выдавать одни и те же результаты при тех же входных данных при любом количестве потоков, в которых метод будет вызываться. Потому что в x и y передаются копии значений. И связи с оригиналом нет.
Код: c#
1.
2.
3.
4.
5.
public long Func1(int x, int y)
{
    Thread.Sleep(100);
    return x * y;
}



а вот этот код нельзя назвать потокобезопасным, потому что параметр p передает ссылку на объект. А сам объект может изменяться одновременно с этим методом и в других местах.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public class MyPoint
{
    public int x {get; set; }
    public int y {get; set; }
}

public long Func1(MyPoint p)
{
    Thread.Sleep(100);
    return p.x * p.y;
}
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606359
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот если бы было

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class A
{
double a,b;

double f(double x, double y, int z)
{
a=x; b=y;
Thread.Sleep(z); //типа что-то делаем
return a+b;
}
}



Вот тогда бы начались проблемы при вызове из разных потоков

Код: c#
1.
2.
A.f(2,2,20);
A.f(3,3,10);



т.к. переменные a и b будут общими для обоих потоков
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606377
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAих методами.

А мне понятно, почему вы запутались.

Слишком технически восприняли идею, что "методы находятся в классе".
Значит типа надо создавать разные методы чтобы не пересекаться.

Но тут классический обьектно ориентированный подоход "как бы" дает сбой - методы в процессе работы программы измениться не могут, и их сделали так, что физический код он один, а устроен так (с помощью стека и управления потоками) что может вызываться откуда угодно.

Вы вобще знаете как работает процессор при переходе типа GOTO 555? Там есть регистр адреса, и вот при обычном проходе адрес просто увеличивается на единицу, а при прямом переходе - в регистр записывается 555 и следующая команда уже будет №555.
То есть, по всей своей немаленькой памяти процессор перемещается мгновенно (за одну операцию).
И это дает возможность свободно использовать общий участок кода (который где-то да, существует!) для всех экземпляров класса.
А вот изменяемую часть - переменные, массивы переменных - это да, пишется в разное место для каждого нового экземпляра.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606388
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PallarisВот если бы было

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class A
{
double a,b;

double f(double x, double y, int z)
{
a=x; b=y;
Thread.Sleep(z); //типа что-то делаем
return a+b;
}
}



Вот тогда бы начались проблемы при вызове из разных потоков

Код: c#
1.
2.
A.f(2,2,20);
A.f(3,3,10);



т.к. переменные a и b будут общими для обоих потоков А именно так, собственно и есть. Но, думаю, и в моем варианте хорошо не закончится. Вечером проведу натурный эксперимент.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606390
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA А именно так, собственно и есть.
Зачем тогда голову морочишь неправильными примерами?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class A
{
     public object syncRoot = new object();
     ....
}
// в каком-то потоке
lock (someA.syncRoot)
{
    A.f(2,2,20);
}

// в каком-то другом потоке
lock (someA.syncRoot)
{
    A.f(3,3,10);
}



Вечером проведу натурный эксперимент.

Удачи
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606398
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAВечером проведу натурный эксперимент.
Проведите лучше мысленный.
Если бы для разделения того, что функция делает, программисту на языке высокого уровня приходилось бы заморачиваться
проблемами низкого уровня - то уже давно бы это изменили.
И уже давно изменили.
:-)
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606404
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
D129YUBAих методами.Вы вобще знаете как работает процессор при переходе типа GOTO 555? Там есть регистр адреса, и вот при обычном проходе адрес просто увеличивается на единицу, а при прямом переходе - в регистр записывается 555 и следующая команда уже будет №555.
То есть, по всей своей немаленькой памяти процессор перемещается мгновенно (за одну операцию).
И это дает возможность свободно использовать общий участок кода (который где-то да, существует!) для всех экземпляров класса.
А вот изменяемую часть - переменные, массивы переменных - это да, пишется в разное место для каждого нового экземпляра.Вообще знаю, и как процессор, и что есть стек, и что туда пишется. А еще и вышивать умею, на ассемблере раньше приходилось, и в машинных кодах тоже.
Именно, отталкиваясь от низкого уровня, все больше полагаю, что 2+2=6. Если в NET MS что-то не придумал.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606475
Фотография D129
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA в NET MS что-то не придумал.

С++ писал не микрософт. Понятие "класс" тоже не их.
:-)
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606490
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAВообще знаю, и как процессор, и что есть стек, и что туда пишется.
не похоже
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606520
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA,
авторА про стек - каждый поток имеет свой стек. == сахар белый
проведите мысленный эксперимент: В стеке вызовов замените вызов функции inline встройкой в вышестоящий стек
у вас че поток загнется? хотя компилятор это делает на ура и даже по принуждению (AggressiveInlining).
или передайте тело как аргумент
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
            new Thread(s => ((Func<double, double, int, double>)s)(1, 2, 3)).
            Start((Func<double, double, int, double>)((x, y, z) =>
            {
                double a, b;
                a = x; b = y;
                Thread.Sleep(z); //типа что-то делаем
                return a + b;
            }));


тут никто не будет бить по рукам за это..
все Ваши фобии вызывают улыбку с ассоциацией юноши, который подрочив боится заразиться триппером ))
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606531
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Результаты натурного эксперимента.
Код: 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.
public class A1
    {
        Thread t1;
        Thread t2;
        B1 B10 = new B1();
          
        public A1()
        {
        t1 =new Thread(dt1);
        t2 =new Thread(dt2);
        t1.Start();
        t2.Start();
        }
        
        void dt1()
        {
            Double x = 2, y = 2;
            Debug.WriteLine("Поток t1", "2+2=");
            Debug.WriteLine(B10.f(ref x,ref y,220), "2+2=");
        }
        
        void dt2()
        {
            for(int i=0; i<5; i++)
            {
                Double x=3,  y=3;
                Debug.WriteLine("Поток t2", "3+3=");
                Debug.WriteLine(B10.f(ref x, ref y, 50), "3+3=");
            }

        }

        double f(double x, double y, int z)
        {
            double a, b;
            a = x; b = y;
            Thread.Sleep(z);
            return a + b;
          }
    
class B1
    {
        public B1()
        { }

        public double f(ref double x, ref double  y, int z)
        {
            double a, b;
            a = x; b = y;
            double c;
            c = a + b;
            String s = x + "" + y + " " + z + " " + c;
            Debug.WriteLine(z, "Задержка");
            Thread.Sleep(z);
            Debug.WriteLine(s);
            return a + b +c+x+y;
        }
   }


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).
Все, как видно, ОК. Каждый поток работает со своим образом функции.
Тема исчерпана.
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606571
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBA,

YUBAсвоим образом функции
Что такое "образ функции" ?)
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606607
YUBA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchЧто такое "образ функции" ?)Образ - описание, модель, копия и т.д., достаточное, для полного восстановления объекта и его свойств.
Как конкретно это реализовано MS не имеет значения.

Да, Всем Спасибо!
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606611
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBALelouchЧто такое "образ функции" ?)Образ - описание, модель, копия и т.д., достаточное, для полного восстановления объекта и его свойств.
кто на ком стоял?(с)
...
Рейтинг: 0 / 0
Многопоточность и разделяемые ресурсы.
    #38606621
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YUBAОбраз - описание, модель, копия и т.д., достаточное, для полного восстановления объекта и его свойств.


Экземпляр метода - он всегда один в памяти.
...
Рейтинг: 0 / 0
25 сообщений из 72, страница 1 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Многопоточность и разделяемые ресурсы.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]