Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.03.21;
Скачать: [xml.tar.bz2];

Вниз

вызов функции из потока   Найти похожие ветки 

 
fford   (2010-01-15 16:29) [0]

Здравствуйте!
Например есть два потока каждый из которых одновременно вызывает одну и туже функцию. т.е.

type
 TThread1 = class(TThread)
  private
  protected
     procedure Execute;override;
  public
     Constructor Create;
 end;
 TThread2 = class(TThread)
  private
  protected
     procedure Execute;override;
  public
     Constructor Create;
 end;

function foo(a,b:Integer):Integer;
Begin
result:=a+b;
End;

Procedure TThread1.Execute;
Var i:Integer;
Begin
i:=foo(10,20);
End;

Procedure TThread2.Execute;
Var i:Integer;
Begin
i:=foo(1,2);
End;



на сколько я знаю функция будет распологаться в кодовом сегмене и при её вызове в стек будут записаны параметры которые ей передались
и которые та достает из стека и собственно с ними уже работает

так вот вопрос,
что будет в переменной I при выполнении Execute обоих потоков одновременно

т.е. одновременно они вызовут эту функцию
каждый из этих вызовов запишет в стек свои параметры
и чтож тогда будет в результате???


 
Джо ©   (2010-01-15 16:32) [1]

У каждого потока своей стек.


 
clickmaker ©   (2010-01-15 16:32) [2]

> что будет в переменной I при выполнении Execute обоих потоков
> одновременно

свои значения для каждого потока


 
fford   (2010-01-15 16:39) [3]


> У каждого потока своей стек.

т.е. при вызове функции передается еще и адрес стека?


 
oxffff ©   (2010-01-15 16:42) [4]

Нет. при создании потока ему выделяется свой стековый сегмент.
см.
CreateThread->dwStackSize
[in] Initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.

Thread Stack Size
Each new thread or fiber receives its own stack space consisting of both reserved and initially committed memory. The reserved memory size represents the total stack allocation in virtual memory. As such, the reserved size is limited to the virtual address range. The initially committed pages do not utilize physical memory until they are referenced; however, they do remove pages from the system total commit limit, which is the size of the page file plus the size of the physical memory. The system commits additional pages from the reserved stack memory as they are needed, until either the stack reaches the reserved size minus one page (which is used as a guard page to prevent stack overflow) or the system is so low on memory that the operation fails.

It is best to choose as small a stack size as possible and commit the stack that is needed for the thread or fiber to run reliably. Every page that is reserved for the stack cannot be used for any other purpose.

A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.

The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. To specify a different default stack size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. For more information on these default sizes and how to change them, see the documentation included with your linker.

To change the initially committed stack space, use the dwStackSize parameter of the CreateThread, CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.

To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx. The committed size is specified in the dwStackCommitSize parameter.

The SetThreadStackGuarantee function sets the minimum size of the stack associated with the calling thread or fiber that will be available during any stack overflow exceptions.


 
clickmaker ©   (2010-01-15 16:43) [5]

стэк - это некоторая область памяти, которая своя у каждого потока
при вызове функции указатель сдвигается, при выходе из функции откатывается


 
fford   (2010-01-15 17:27) [6]

провел эксперимент
в рабочей программе сделал класс потока куда запихнул довольно продолжительную по выполнению функцию в процессе выполнения котрой она вызывает другие процедуры

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

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

например, используя код из вопроса, такие вызовы безопасны
но если функция
foo будет такой

function foo2(a,b:Integer):Integer;
Begin
a:=a+100;
b:=b*100;
result:=a+b;
End;

function foo(a,b:Integer):Integer;
Begin
result:=foo2(a,b)+b+foo2(b,a);
End;


при выполнение функции foo2 процесс может не дойти до конца т.к. будет вызван при выполнении foo из другого потока

о как


 
clickmaker ©   (2010-01-15 17:46) [7]

> вот вызовы из нее других функций не выполнялись до конца
> и перескакивая на вызовы из других потоков

Как выяснил?
функции, которые используют только локальные переменные - потокобезопасны.


 
Сергей М. ©   (2010-01-15 21:21) [8]


> при выполнение функции foo2 процесс может не дойти до конца


Может и не дойти.
Но только не по причине мнимой тобой в  [6] потоконебезопасности алгоритма.

В [6] нет  ни намека на обращение к потоконебезопасным данным


 
Игорь Шевченко ©   (2010-01-15 21:42) [9]


> при выполнение функции foo2 процесс может не дойти до конца
> т.к. будет вызван при выполнении foo из другого потока


Ты открыл для себя вытесняющую многозадачность ?
Поздравляю!
Не поздно ? Ей уже лет 30 минимум



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.03.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.006 c
4-1226836612
kolj
2008-11-16 14:56
2010.03.21
Проблема с SendMessage


6-1214365922
brother
2008-06-25 07:52
2010.03.21
TWebBrowser


15-1262441446
AlexDan
2010-01-02 17:10
2010.03.21
реклама от гугла..


2-1263741218
@!!ex
2010-01-17 18:13
2010.03.21
Как поместить кнопку на Caption в Windows Vista and later


2-1263392044
Виталий Панасенко
2010-01-13 17:14
2010.03.21
АДО и master-detail





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский