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

Вниз

Обращение к ф-цииDLL одновременно из нескольких процессов   Найти похожие ветки 

 
Alex_C ©   (2007-06-13 18:54) [0]

Есть DLL, в ней есть ф-ция, в качестве аргумента принемающая некою структуру и заполняющая ее в зависимости от того, какие поля были заполнены.
В приложении несколько TTreads, которые обращаются к ф-ции данной DLL (DLL статический вызов).
Естественно, когда одновременно 2 TThread обращаются к данной ф-ции возникает ошибка. Как этого избежать?
Пробовал в DLL в  функцию ставил TRTLCriticalSection - не помогает, ведь входная структура портится, если в это время опять идет обращение к этой ф-ции.
Какие еще есть варианты?


 
Правильный Вася   (2007-06-13 19:10) [1]

ThreadSafe=True
глобальные переменные?
?


 
DrPass ©   (2007-06-13 22:50) [2]


> ведь входная структура портится, если в это время опять
> идет обращение к этой ф-ции

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


 
Правильный Вася   (2007-06-13 23:04) [3]

сорри, в секции инициализации DLL
 IsMultiThread := True;


 
Eraser ©   (2007-06-13 23:39) [4]

> [0] Alex_C ©   (13.06.07 18:54)


> Обращение к ф-цииDLL одновременно из нескольких процессов

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


 
Сергей М. ©   (2007-06-14 08:22) [5]


> Eraser ©   (13.06.07 23:39) [4]


> необходимо защитить функцию


Защищают не функцию, а ресурсы.
В случае автора таким ресурсом, вероятно, являются те самые структурированные данные, передаваемые фактическим параметром при вызове функции.


 
Alex_C ©   (2007-06-14 08:26) [6]

Ребята большое спасибо за советы!
Еще такой вопрос:
есть ф-ция (причем как я пинимаю не важно - в DLL она или просто в теле проги)

Func( A: String ):Integer;
begin
    EnterCriticalSection...

Вопрос:
при вызове ее одновременно допустим из 3-х Thred"ов, они дойдут до CriticalSection и будут ждать, пока можно будет идти дальше, тут понятно. А переменная А для каждых вызовов своя будет? Т.е. стек отдельный для каждого вызова и портится он не будет?


 
Alex_C ©   (2007-06-14 08:29) [7]

Да и еще в добавок: если ф-ция находится в DLL, то надо использовать уже не CriticalSection, а Мютексы?


 
Сергей М. ©   (2007-06-14 08:40) [8]


> переменная А для каждых вызовов своя будет?


Да, своя.
Только это не переменная, а параметр (аргумент) функции.


> стек отдельный для каждого вызова и портится он не будет?


Стек отдельный для каждого потока, а не для каждого вызова.
В дан.случае стек при передаче параметра вообще не испольщуется - параметр передается в регистре eax процессора.


> если ф-ция находится в DLL, то надо использовать уже не
> CriticalSection, а Мютексы?


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


 
Alex_C ©   (2007-06-14 09:33) [9]

То Сергей М. : большое спасибо за столь подробный и понятный ответ!
Тут все ясно - все заработало как надо!
И еще вопрос:
можно ведь обойтись и без CriticalSection, с помощью глобальной переменной вот так:

While WaitWhileEnd do
   Application.ProcessMessage;
ну и далее
  WaitWhileEnd := True;
  // текст проги
  WaitWhileEnd := False;

Чем плох такой метод?


 
Loginov Dmitry ©   (2007-06-14 10:58) [10]

> можно ведь обойтись и без CriticalSection, с помощью глобальной
> переменной вот так:
>
> While WaitWhileEnd do
>   Application.ProcessMessage;
> ну и далее
>  WaitWhileEnd := True;
>  // текст проги
>  WaitWhileEnd := False;


и что даст Application.ProcessMessage? Только дополнительные грабли, особенно, если данный код начнет вызываться из дополнительных потоков. Чуть надежнее будет, если вместо него вставить, скажем, Sleep(50) - меньше нагрузки на процессор, но и это отвратительный выход, так как цикл ожидания запросто может одновременно завержиться у двух потоков и они одновременно перейдут к выполнинию "текста проги". Единственный надежный способ защиты ресурсов - использование критической секции либо объектов синхронизации.


 
Сергей М. ©   (2007-06-14 11:28) [11]


> Чем плох такой метод?


Тем что его использование рано или поздно приведет к успешной попытке захвата защищаемого ресурса более чем одним потоком - между строчками

While WaitWhileEnd do

и

WaitWhileEnd := True;

запросто может произойти переключение контекста потоков



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

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

Наверх





Память: 0.48 MB
Время: 0.046 c
15-1185885205
click
2007-07-31 16:33
2007.08.26
Посоветуйте литературу


2-1185899291
Kaer
2007-07-31 20:28
2007.08.26
Работа с бд Ms Access


15-1185349224
ПЛОВ
2007-07-25 11:40
2007.08.26
SQL


2-1186122751
p_evghenii
2007-08-03 10:32
2007.08.26
Как подождать завершения чужого процесса


1-1182243710
DrAndrew
2007-06-19 13:01
2007.08.26
Ошибка #10061 у IdHTTP1. Как исправить?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский