Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.02.01;
Скачать: CL | DM;

Вниз

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

 
QAZ   (2014-07-01 15:30) [0]

Есть DLL скомпиленая на С, конкретно в С++ Builder
все ее функции используют глобальные переменные
прога написанная на дельфи вызывает эти функции сразу с Х потоков
в итоге получается каша и все крашится, с одним потоком все норм, линковка статическая
какие есть варианты этого избежать без объявления каждой глобальной переменной в DLL как __thread ?
собственно при создании DLL в мастере ставится галочка Multi Threaded, но толку от нее никакого видимо

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


 
это все   (2014-07-01 15:53) [1]

консольная подпорка.
потоки запускают ее (новый процесс)
консолька дергает длл и получает результ.
параметры и результат гонять через переопределенные для консольки stdin/stdout


 
Sha ©   (2014-07-01 15:54) [2]

> все ее функции используют глобальные переменные

для чего?


 
Ega23 ©   (2014-07-01 15:57) [3]

Если есть исходники для dll, то переделать её под threadsafe
Если нет - сделать шлюз по обращению к dll, с критсекцией.


 
QAZ   (2014-07-01 16:26) [4]


> для чего?

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

> Если есть исходники для dll, то переделать её под threadsafeЕсли
> нет - сделать шлюз по обращению к dll, с критсекцией.

а можно прямую ссылку\пример (без гугла) по обоим вариантам?
ибо конкретно с переделкой будет проблема в плане 0 знаний по С
__thread (с которым собственно все работает) относится к решению "переделать её под threadsafe" ?


 
Sha ©   (2014-07-01 16:56) [5]

> QAZ   (01.07.14 16:26) [4]

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


 
DVM ©   (2014-07-01 17:24) [6]


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

Нет исходников библиотеки и известно что она непотокобезопасна? Нет проблем. Было у меня как то такое с серверной библиотекой от Lotus Notes. Решилось так: в интерфейсном модуле к библиотеке обертываем вызовы всех функций библиотеки критической секцией и все. Другого не дано все равно.


 
QAZ   (2014-07-01 17:24) [7]


> Sha ©   (01.07.14 16:56) [5]

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


 
QAZ   (2014-07-01 17:27) [8]


> DVM ©   (01.07.14 17:24) [6]

то есть, как бы это будет работать также как и при одном потоке, то есть вообще не параллельно, но работать?


 
Sha ©   (2014-07-01 17:27) [9]

> QAZ   (01.07.14 17:24) [7]

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


 
DVM ©   (2014-07-01 17:28) [10]

Но от этого не появится возможности работать с несколькими наборами данных внутри библиотеки, если она сама эти данные хранит в глобальных переменных.
Самый простой вариант тут - Unix Way - множество процессов в каждый из которых загружена своя копия библиотеки и какое то взаимодействие между ними.


 
DVM ©   (2014-07-01 17:29) [11]


> QAZ   (01.07.14 17:27) [8]


> то есть, как бы это будет работать также как и при одном
> потоке, то есть вообще не параллельно, но работать?

Да. Но может там что-то и удастся распараллелить, может там не все функции нуждаются в обертке.


 
Sha ©   (2014-07-01 17:31) [12]

> DVM ©   (01.07.14 17:24) [6]

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


 
DVM ©   (2014-07-01 17:33) [13]


> Sha ©   (01.07.14 17:31) [12]

ну да, я это в [10] и имел в виду.


 
QAZ   (2014-07-01 17:34) [14]

а что всетаки скажете про __thread аналог(я так думаю) дельфийской threadvar ?
просто оно реально работает, но мало ли, может какие тонкости есть
собственно одна из них это "вбивание" содержимого всех переменных в бинарник dll компилятором билдера
то есть если глобал. переменная = массив в 1 Мб, то этот 1 Мб в зануленном виде будет "вбит" в код dll :)


 
Sha ©   (2014-07-01 17:52) [15]

> QAZ   (01.07.14 17:34) [14]

чем это лучше локальных переменных в execute?


 
QAZ   (2014-07-01 18:05) [16]


> Sha ©   (01.07.14 17:52) [15]

низнай :) у меня и execute то нет, я не пользую VCL
я так понял при threadvar\__thread копии локальных создаются для каждого потока и вроде не должно быть проблем

вот еще накопал в справке про некие глобальные переменные IsMultiThreaded присутствующие в дельфи и билдере, вот текст
If a C++Builder DLL module is loaded into a multithreaded host EXE (C++Builder, Delphi or otherwise), the DLL must set its IsMultiThreaded global variable to true to enable the thread protection mechanisms inside the heap manager. There is no other way for the DLL heap manager to find out that it is going to be used in a multi-threaded manner. Similarly, C++Builder code that spawns new threads should always do so using System::BeginThread rather than the low-level Win32 API CreateThread.
гугл-транслэйт меня опечалил, но я так примерно предполагаю что это относится чисто к "магии" VCL и на чистый С код не повлияет ?
и не сводится ли этот механизм опять же к варианту DVM ©   (01.07.14 17:24) [6] ?


 
Sha ©   (2014-07-01 19:40) [17]

> QAZ   (01.07.14 18:05) [16]

Для мультипоточного приложения обязано быть IsMultiThreaded=true.
Об этом обычно заботится Delphi.
Но если ты сам химичишь с потоками, сам выставляй как требуется.


 
han_malign   (2014-07-02 17:27) [18]


>  Unix Way - множество процессов в каждый из которых загружена
> своя копия библиотеки

- ну либо PE-Loader - без подсчета ссылок, правда при этом и секции кода дублироваться будут(т.к. мудри не мудри, а ссылки на секцию данных по любому в rebase попадут)...


> указатель на некий мегоrecord

- классическая реализация ООП в функциональной декомпозиции(WinAPI например) - алокатор/деалокатор ссылки на контекст + аксессоры...


> я так понял при threadvar\__thread копии локальных создаются
> для каждого потока и вроде не должно быть проблем

- ну-ну - если это скаляры с разрядностью не превышающие разрядности приложения - то без проблем.
А если это сложно-составные объекты - то DLL_THREAD_ATTACH/DLL_THREAD_DETACH - сущность крайне странная и капризная - а значит здравствуй утечка памяти...



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

Текущий архив: 2015.02.01;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.006 c
15-1404214218
QAZ
2014-07-01 15:30
2015.02.01
Вызов функций DLL из разных потоков


15-1404104982
куку
2014-06-30 09:09
2015.02.01
dbv-t2


15-1404160205
Юрий
2014-07-01 00:30
2015.02.01
С днем рождения ! 1 июля 2014 вторник


15-1403806033
0xdeadc0de
2014-06-26 22:07
2015.02.01
AppMethod vs RAD Studio XE6


1-1329509303
Hgd1
2012-02-18 00:08
2015.02.01
Печать на принтер