Сейчас на форуме: hgdagon, asfa (+4 невидимых)

 eXeL@B —› Программирование —› Delphi TThread теоритический вопрос
Посл.ответ Сообщение

Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 06 февраля 2007 09:36
· Личное сообщение · #1

Доброго здравия!
Интересует по теме вот что: есть мой класс TMyThread, метод Execute и всё аткое прочее, как полагается. Если я создам 100 экземпляров данного класса и работать они будут без всякой синхронизации - каждый сам по себе, то насчет переменных понятно, а вот метод всего один (код не создается и не дублируется в отличае от данных класса) и что тогда произойдет при его вызове несколькими потоками?
Немного перефразирую: будет ли каждый экземпляр класса выполняться в своем контексте или нет?

Извините еслинеясно выразился или если где ошибки. поранил руку и очень неудобно набивать текст а ещё по запарке выключил комп клавишей power на клаве =(

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 240.5 (наставник)
Активность: 0.190
Статус: Участник
Author of ACKiller

Создано: 06 февраля 2007 09:44
· Личное сообщение · #2

Смотря как будешь вызывать этот метод - если одним потоком, то последовательно тем же потоком, если разными - то в различных контекстах=)
Если код не успользует глобальные переменные, то ему должно быть глубоко по барабану сколько потоков его выполняют и в каком порядке - хоть два ядра одновременно!




Ранг: 105.9 (ветеран)
Активность: 0.060
Статус: Участник

Создано: 06 февраля 2007 09:55
· Личное сообщение · #3

Методы, классы- ненавижу ооп. Если 100 потоков без синхронизации вызывают общую функцию, которая не работает с глобальными переменными то все будет ок. Контекст - это структура потока, при чем тут классы? А вообще, запусти ProcessExplorer и посмотри, что в каком потоке выполняется.



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 06 февраля 2007 10:43
· Личное сообщение · #4

HoBleen
seeq
Насчет глобальных переменных всё верно, т.к. по определению на каждый объект выдаются свои данные, а методы общие для всех, т.к. при вызове метода параметром передается сцылка на вызвавший его объект.

Вообще я представляю вот как:
TMyThread1 = class(TThread)
TMyThread2 = class(TThread)
...
TMyThreadN = class(TThread)
Если создать по одному объекту каждого класса и учесть что классы абсолютно идентичны, тогда система разделит процессорное время и каждый объект будет иметь свой кусок кода. А если мы плодим TMyThread 100 раз, то будет ли это правильным? Хотя всё равно понятие одновременного выполнения трэдов звучит "странно", сами догадываетесь почему (многозадачная ОС и распределение процессорного времени по очереди).
Правда в том, что сколько бы тредов не было, всё равно выполняться одновременно не будут, а значит контексты должны быть своими. Или я заблуждаюсь?

-----
Я медленно снимаю с неё UPX... *FF_User*




Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 06 февраля 2007 10:46
· Личное сообщение · #5

HoBleen пишет:
Смотря как будешь вызывать этот метод - если одним потоком, то последовательно тем же потоком, если разными - то в различных контекстах

Я не совсем понял эту фразу. Что значит "вызывать метод одним потоком или несколькими"? Экзекут - это и есть сам поток (трэд).

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 240.5 (наставник)
Активность: 0.190
Статус: Участник
Author of ACKiller

Создано: 06 февраля 2007 10:50
· Личное сообщение · #6

У тебя каша в голове по поводу контекста. Контекст - грубо говоря собственность потока.
Если код выполняется одним потоком, то значит и в одном и том же контексте. Почитай Рихтера.

AlexZ пишет:
всё равно выполняться одновременно не будут
Хотя всё равно понятие одновременного выполнения трэдов звучит "странно",

А если многопроцессорная система?

AlexZ пишет:
будет ли каждый экземпляр класса выполняться в своем контексте или нет?

Зачем тебе это надо знать?




Ранг: 105.9 (ветеран)
Активность: 0.060
Статус: Участник

Создано: 06 февраля 2007 12:01
· Личное сообщение · #7

AlexZ пишет:
HoBleen
seeq
Насчет глобальных переменных всё верно, т.к. по определению на каждый объект выдаются свои данные, а методы общие для всех, т.к. при вызове метода параметром передается сцылка на вызвавший его объект.

Я наверно окончательно тебя запутаю, если скажу, что это верно по причине, что у каждого потока свой стек. А то что ты написал, никакого отношения к многозадачности не имеет.

HoBleen пишет:
У тебя каша в голове

Классы, потоки, методы ты все смешал в кучу.

AlexZ пишет:
Правда в том, что сколько бы тредов не было, всё равно выполняться одновременно не будут, а значит контексты должны быть своими. Или я заблуждаюсь?

У каждого потока свой контекст. Если многопроцессорная система то будут.



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 06 февраля 2007 12:29
· Личное сообщение · #8

seeq
HoBleen
Система максимум двухъядерная

HoBleen пишет:
Зачем тебе это надо знать?

Для того чтобы можно было беззаботно плодить объекты класса TXXXXXThread. С другой стороны, на блокирующих сокетах так и должно происходить, значит я думаю что можно.

/me совсем запутался

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 06 февраля 2007 16:24 · Поправил: s0larian
· Личное сообщение · #9

AlexZ смотри - работает это вот как. Забудем про OOP на минуту.


DWORD WINAPI ThreadBody(void *arg)
{
for (int i = 0; i < 10; ++i)
{
printf("i=%d\n", i);
sleep(1);
}
}

int main()
{
CreateThread(ThreadBody, 0);
CreateThread(ThreadBody, 0);
CreateThread(ThreadBody, 0);
CreateThread(ThreadBody, 0);

for (;;)
sleep(1);

return 0;
}


вот прога которая создаёт несколько потоков и потом вызывает sleep(). Созданые потоки в финале вызовут ThreadBody. В ней есть одна локальная переменная (то есть на стеке) и один вызов printf(). У каждого потока свой стек и, следовательно, у тебя есть 4 разных "i" на 4ёх стеках. Относительно их и крутятся циклы.

Каждый поток в системе NT получает процессорное время, и может крутить цикл. при этом исполняется код из какой-то секции PE файла. При переключении потоков (скажем внутри этого процесса) система должна всево-лишь заменить регистры (вреди них есть и ESP/EBP). Это и есть контекст.

То есть, всё что находися на стеке - лежит в отдельном куске памяти, на который показывают ESP/EBP потока. Следовательно тебе не надо ничего защищить mutex-ами. Глобальные переменные лежат в data секции и их "видят" все потоки.

Теперь про OOP. Обычно конструктор вызывается в контексте главного потока, а Derived::OnRun() в контексте нового потока.

P.S. набей такую прогу и запусти. Посмотри вывод. Помучай отладчиком.



Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 06 февраля 2007 20:25 · Поправил: theCollision
· Личное сообщение · #10

AlexZ
Если ты читал(а) Страуструпа, то ты должен шарить, что под объект класса выделяется Только и только память!!! Из этих слов следует, что под каждый объект свои данные, с которыми оперирует тот или иной метод, следовательно код метода ... эээ... вроде реентерабельность это называется(не помню). Кароче скоко раз не входи и каким кол-вом потоков ему пофиг!

Напиши простенький класс и глянь, ты увидишь код, уверяю отладчик не такой уж и страшный!

-----
My love is very cool girl.




Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 06 февраля 2007 23:53
· Личное сообщение · #11

theCollision пишет:
Если ты читал(а) Страуструпа, то ты должен шарить, что под объект класса выделяется Только и только память!!! Из этих слов следует, что под каждый объект свои данные, с которыми оперирует тот или иной метод

Я не читал Страуструпа и знаю что для объектов AlexZ пишет:
код не создается и не дублируется в отличае от данных класса


s0larian пишет:
Каждый поток в системе NT получает процессорное время, и может крутить цикл. при этом исполняется код из какой-то секции PE файла. При переключении потоков (скажем внутри этого процесса) система должна всево-лишь заменить регистры (вреди них есть и ESP/EBP). Это и есть контекст.

Вот это и нужно было уточнить. thx, хороший ответ.

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 110.0 (ветеран), 1thx
Активность: 0.090
Статус: Участник

Создано: 07 февраля 2007 09:48
· Личное сообщение · #12

Если нужны глобальные переменные для каждого потоко отдельно, то можно использовать threadvar вместо var

-----
Никто не знает столько, сколько не знаю я





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 07 февраля 2007 10:06
· Личное сообщение · #13

AlexZ, ну в догонку тебе вот ещё - для каждого куска кода ты можешь посмотреть где расположены переменные/атрибуты которыми ты оперируешь. Например ты можешь выделить (allocate) объект на стеке внутри потока и вызывать его методы. В этом случае код будет обращаться к instance лежащей на стеке. Ну а если объект уже выделен и ты им пользуешься из нескольких потоков - то тут нужна синхронизация.


 eXeL@B —› Программирование —› Delphi TThread теоритический вопрос
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати