![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Эта проблемная многопоточность [D7, WinXP]
Vilux © (2004-11-22 09:59:00)Создаю много потоков и в каждом потоке подключаю dll функцией
hinstDLL := LoadLibrary(pchar(dllname));
И пишу логи. В логах видно, что в каждом потоке hinstDLL имеет одно и то же значение... так и должно быть? Дело в том, что моя программа вылетает, когда одновременно в потоках пытается подключиться dll-ка и вызваться процедура из нее... но если в каждом потоке подключать dll-ку через Synchronize, то прога не вылетает. Но зато очень медленно. Такое впечатление, что использование SYnchronize отменяет весь эффект многопоточности. Как быть? Как мне в потоках отркывать одновременно одну dll-ку и чтобы без вылетов?
Digitman (2004-11-23 15:03:00) [1]
> Vilux © (23.11.04 14:32) [15]
> dll нужна по-любому, это позволяет наращивать модульность
> программы
гадиматья.
механизм динамически линкуемых библиотек был придуман и реализован отнюдь не для этого
TUser (2004-11-23 15:02:00) [2]
> Vilux © (23.11.04 14:13) [9]
Ты точно уверен, что тормоза возникают на подгрузке dll, а не от того, что сервер базы данных не может обрабатывать много запросов?
В любом случае, я бы сделал загрузку dll только один раз. И флаг какой-нибудь, типа 'dll загружена'. Тогда потоки ничего грузить пытаться не будут, а будут просто получать готовый хендл.
Alexander Panov (2004-11-23 14:56:00) [3]Vilux © (23.11.04 14:32) [15]
Вот это что - http://www.delphimaster.ru/cgi-bin/forum.pl?id=1101205723&n=1?
Нехорошо спамом заниматься.
Alexander Panov (2004-11-23 14:54:00) [4]Vilux © (23.11.04 14:32) [15]
По поводу одинх и тех же адресов:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1101141727&n=0
Vilux (2004-11-23 14:32:00) [5]dll нужна по-любому, это позволяет наращивать модульность программы. Т.е. написал новую dll и просто указал программе в каком случае ее запускать. При этом не придется трогать исходники самой программы
Vilux (2004-11-23 14:30:00) [6]ну... я думал проблема в том, что потоки пытаются одновременно вызвать функцию, которая расположена по одному и тому же адресу. Или не так?
sniknik (2004-11-23 14:30:00) [7]может убрать их? и сделать на ассинхронных запросах (выполнение в потоках внутри ADO).
и dll возможено не нужна вовсе...
Alexander Panov (2004-11-23 14:28:00) [8]Vilux © (23.11.04 14:25) [11]
я уже понял, так как мне тогда решить мою проблему? чтобы не было конфликтов между потоками...
Так это не проблема.
Вот только неизвестно, в чем она у тебя - кода-то никто до сих пор не увидел.
Vilux (2004-11-23 14:25:00) [9]я уже понял, так как мне тогда решить мою проблему? чтобы не было конфликтов между потоками...
Alexander Panov (2004-11-23 14:16:00) [10]Vilux © (23.11.04 14:13) [9]
DLL загружается в твой процесс, а не в поток, и в любом потоке адрес будет одинаков.
Vilux (2004-11-23 14:13:00) [11]Описываю задачу...
есть сервер, который получает данные на вход и запускает поток. В этом потоке в зависимости от полученных данных пускается определенная dll-ка, которая работает с БД(Access) через ADO-компоненты. Нужно, чтобы все это работало быстро. Как я выяснил, прога виснет, когда создается много потоков и каждый поток через функцию dll пытается работать с БД. Т.е. мне надо, чтобы в каждом потоке подргужалась dll-ка в новую область памяти. А то получается, что я в потоках подгружаю dll и думаю, что и функции из нее в каждом потоке расположены по разным адресам, а оказывается, что все потоки одновременно обращаются к функции по одному и тому же адресу(судя по тому, что hinstdll везде одинаков), отсюда походу и идут все косяки
TUser (2004-11-22 10:37:00) [12]
> если в каждом потоке подключать dll-ку через Synchronize,
> то прога не вылетает. Но зато очень медленно. Такое впечатление,
> что использование SYnchronize отменяет весь эффект многопоточности
S выполняет код от имени главного потока приложения. Так что все выполняется в одном потоке, а подгрузка dll - дело действительно довольно медленное. С другой стороны, оно хоть и медленное, но обычно однократное - подгрузили и работаем, так что заметных тормозов быть не должно. А вот если ты ее подгружаешь много раз (ты ведь создаешь многопотоков) - то действительно может тормозить.
Судя по тому, что хендл везде получется один и тот же, ты грузишь одну и ту же библиотеку - а она грузится в адресное пространство процесса, причем один раз. Но попыток загрузить ее получется много, причем все в контексте главного потока. А это плохо.
Непонятно - почему бы не загрузить dll один раз в главном потоке и передать всем остальным потокам ее хендл.
PS. На этом форуме переодиечски появляются вопросы про много потоков- часто оказывается, что их так много и не надо. Опиши свою задачу, много потоков реально необходимо для очень небольшого количества задач, таких как обслуживание многихпользователей на крутых серверах и т.д.
Reindeer Moss Eater (2004-11-22 10:36:00) [13]Тебе ж говорят, что у тебя ошибка в программе.
Vilux (2004-11-22 10:33:00) [14]ПРовел еще один тест... если dll-ка пустая, то все работает*(т.е. из кучи потоков запускается без проблем). А если я там какие-нибудь переменные ввожу и все, больше ничего, никаких процедур не вызываю, ничего... то тогда прога вылетает...просто исчезает.
ggs (2004-11-22 10:32:00) [15]
> hinstDLL имеет одно и то же значение... так и должно быть?
Да, DLL проецируется на адресное пространство твоего процесса,
а hinstDLL и есть это адрес.
> Дело в том, что моя программа вылетает, когда одновременно
> в потоках пытается подключиться dll-ка и вызваться процедура
> из нее...
ХЗ... возможно один поток вызывает FreeLibrary а потом вытается
использовать функцию из DLL, в общем "ошибка в программе" ;)
> Такое впечатление, что использование SYnchronize отменяет
> весь эффект многопоточности.
Не совсем так... посмотри реализацию Synchronize в VCL.
> Как быть?
Загружай/выгружай DLL в основном потоке, а в рабочих используй
GetModuleHandle(Ex)...
Digitman (2004-11-22 10:32:00) [16]
> в каждом потоке hinstDLL имеет одно и то же значение...
> так и должно быть?
да
> использование SYnchronize отменяет весь эффект многопоточности
на то Synchronize и нужен
Reindeer Moss Eater (2004-11-22 10:21:00) [17]Мне интуиция и здравый смысл это подсказывают.
А так же личный опыт.
Vilux (2004-11-22 10:17:00) [18]Reindeer Moss Eater, а конкретнее? Почему ты так решил?
Reindeer Moss Eater (2004-11-22 10:05:00) [19]У тебя ошибка в программе