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

Вниз

Вызов функций 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.002 c
1-1329509303
Hgd1
2012-02-18 00:08
2015.02.01
Печать на принтер


6-1274425101
VirEx(work)
2010-05-21 10:58
2015.02.01
TcpServerAccept и frmFile.ShowModal


2-1388344091
Wadimka
2013-12-29 23:08
2015.02.01
Как подсчитать, входит ли указанный цвет градиент?


2-1388846664
Андрей Котов
2014-01-04 18:44
2015.02.01
Сетевое приложение на РНР


15-1403209803
Юрий
2014-06-20 00:30
2015.02.01
С днем рождения ! 20 июня 2014 пятница





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