Параллельный вызов dll

Простейшие вопросы в области инженерной разработки
Ответить
Аватара пользователя
Usss
I/O
I/O
Сообщения: 138
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2018

Параллельный вызов dll

Сообщение Usss »

Tcp sniffer скачал когда-то с форума ni. Там dll обращается к winpcap. Все работает хорошо пока нет нужды обращаться одновременно к двум сетевым устройствам. Я эту проблему решил просто создав копию библиотеки dll с новым именем и теперь вызываю две одинаковых библиотеки параллельно. А может есть кошерный способ не городить копий?

Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
professor
professor
Сообщения: 4953
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 2 раза
Поблагодарили: 3 раза

Re: Параллельный вызов dll

Сообщение IvanLis »

Usss писал(а):
18 май 2020, 23:00
А может есть кошерный способ не городить копий?
Я аналогичным образом делал, когда выполнял захват изображения с двух USB-Cam посредством DLL.

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

Artem.spb

Activity Автор
expert
expert
Сообщения: 1992
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 5 раз
Поблагодарили: 8 раз
Контактная информация:

Re: Параллельный вызов dll

Сообщение Artem.spb »

"Поддерживаю предыдущего оратора"
У нас в отделе живут dll обоих типов. Если разработчик позаботился о параллельности, то работаем с одним экземпляром.
Если нет, то параллелим клонированием. Вплоть до того, что определяем количество процессоров в машине и программно создаём копии dll, а в реентрантную функцию передаём имя клона, с которым она уже работает.
Если у вас заранее известно количество копий, то можно так не заморачиваться.
Библиотеку качать лень. Но если там есть какой-то хэндлер вызова, то шансы на параллельность есть.

Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3529
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2020
Благодарил (а): 2 раза
Поблагодарили: 9 раз
Контактная информация:

Re: Параллельный вызов dll

Сообщение dadreamer »

From my perspective, WinPcap's binding adapters is designed to be reentrant, as no shared variables are used. And the NdisOpenAdapter function called by WinPcap should be reentrant too according to MSDN: https://msdn.microsoft.com/en-us/library/ee481122.aspx.
( https://seclists.org/nmap-dev/2015/q3/347 )
В большинстве случаев функции WinAPI реентерантны, если на MSDN явно не указано иначе. Функции WinPCap должны быть тоже, разработчики на это намекают: https://www.winpcap.org/pipermail/winpc ... 01674.html Остаётся только враппер lvwpcap.dll, т.к. внутри SubVI всё CLFN'ы уже жёлтые (Any Thread). Детально в исходник нет времени вникать, бегло посмотрел lvwpcap.cpp. В целом довольно неплохо написано, единственная глобальная переменная это pcap_if_t *gDevices. То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать. А что конкретно не работает?

Аватара пользователя
Usss
I/O
I/O
Сообщения: 138
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2018

Re: Параллельный вызов dll

Сообщение Usss »

dadreamer писал(а):
19 май 2020, 08:25
From my perspective, WinPcap's binding adapters is designed to be reentrant, as no shared variables are used. And the NdisOpenAdapter function called by WinPcap should be reentrant too according to MSDN: https://msdn.microsoft.com/en-us/library/ee481122.aspx.
( https://seclists.org/nmap-dev/2015/q3/347 )
В большинстве случаев функции WinAPI реентерантны, если на MSDN явно не указано иначе. Функции WinPCap должны быть тоже, разработчики на это намекают: https://www.winpcap.org/pipermail/winpc ... 01674.html Остаётся только враппер lvwpcap.dll, т.к. внутри SubVI всё CLFN'ы уже жёлтые (Any Thread). Детально в исходник нет времени вникать, бегло посмотрел lvwpcap.cpp. В целом довольно неплохо написано, единственная глобальная переменная это pcap_if_t *gDevices. То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать. А что конкретно не работает?
Пример скачивал кажется от сюда https://forums.ni.com/t5/Example-Code/E ... anguage=en Все виайки класса сделал Preallocated.
На скрине я параллельно вызываю функцию определения списка текущих сетевых устройств. По идее рузельтат должен быть одинаков в обоих случаях. Но он разный. Тоже самое получается при вызове функции RadPacket. Пакеты приходят с потерями, либо вообще работает только одна копия vi
Вложения
параллельный вызов
параллельный вызов
результат
результат

Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
professor
professor
Сообщения: 4953
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 2 раза
Поблагодарили: 3 раза

Re: Параллельный вызов dll

Сообщение IvanLis »

dadreamer писал(а):
19 май 2020, 08:25
То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать.
Попробуйте инициализацию и финализацию сделать одну на два потока.

Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3529
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2020
Благодарил (а): 2 раза
Поблагодарили: 9 раз
Контактная информация:

Re: Параллельный вызов dll

Сообщение dadreamer »

Usss, так пробовали?
IvanLis писал(а):
19 май 2020, 14:58
Попробуйте инициализацию и финализацию сделать одну на два потока.

Аватара пользователя
Usss
I/O
I/O
Сообщения: 138
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2018

Re: Параллельный вызов dll

Сообщение Usss »

IvanLis писал(а):
19 май 2020, 14:58
dadreamer писал(а):
19 май 2020, 08:25
То есть, инициализация (lvwpcap_init <- Initialize.vi) и финализация (lvwpcap_uninit <- Uninitialize.vi) должны всегда вызываться однократно. Остальным функциям без разницы, как их будут вызывать.
Попробуйте инициализацию и финализацию сделать одну на два потока.
Спасибо! Это действительно сработало

Ответить

Вернуться в «Для чайников»