Конференция "Прочее" » Многопоточность и Delphi
 
  • Пробегал2... (25.04.08 19:18) [60]
    Игорь Шевченко ©   (25.04.08 19:05) [59]
    потоки не создаются в DLL. Потоки создаются в процессе


    а вам доставляет удовольствие цепляться к словам? Любопытно посто.

    Если действительно непонятна фраза "потоки созданные в DLL" - я уточню. Это потоки, которые созданы в том месте маш. кода, который был загружен в ВАП процесса при проецировании образа DLL.

    К чему еще изволите придраться?
  • Игорь Шевченко © (25.04.08 19:23) [61]
    Пробегал2...   (25.04.08 19:18) [60]

    И чем они отличаются от потоков, созданных в другом месте кода ?
  • Сергей М, (25.04.08 19:30) [62]

    > Пробегал2...   (25.04.08 19:18) [60]


    > Это потоки, которые созданы в том месте маш. кода, который
    > был загружен в ВАП процесса при проецировании образа DLL


    Не нало месить кислое и фиолетовое.
  • Пробегал2... (25.04.08 20:35) [63]
    Игорь Шевченко ©   (25.04.08 19:23) [61]
    И чем они отличаются от потоков, созданных в другом месте кода ?


    тем, что потоки созданные в DLL должны уничтожаться также в DLL. Это логичная методика работы.

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

    С таким же успехом и глобальные переменные, выделенные в DLL - можно очищать в самом приложении, не так ли? Только это нелогично, это - неудобно.

    Плюс весь WinApi спроектирован таким образом и я думаю стоит придерживаться этого подхода. Когда вам требуется принять некую структуру данных - ВЫ выделяете память под нее и передаете на нее ссылку, по которой эта структура заполняется библиотекой.
    Заметьте, не библиотека выделяет память и передает ссылку на заполненную структуру, которую ВЫ потом должны уничтожить.
    Принцип один: если намусорил - подчисти за СОБОЙ.

    И если там какая-то DLL создала поток для реализации функционала - она же этот поток и должна уничтожить. Имхо, если DLL хорошо спроектирована - то я в любое время могу вызывать FreeLibrary - и DLL должна очистить все ресурсы, занятые ею в процессе работы и вернуть все в то состояние, которое было до вызова LoadLibrary.
  • Игорь Шевченко © (25.04.08 20:42) [64]
    Пробегал2...   (25.04.08 20:35) [63]

    Это всего лишь твое имхо. Ни больше, ни меньше.
    В системе и в приложениях есть примеры и одного подхода, и другого, не надо выдавать свое имхо за абсолютную истину, а главное, делать из этого имха какие-то глобальные выводы.
  • Сергей М, (25.04.08 20:43) [65]
    Удалено модератором
  • Сергей М, (25.04.08 21:00) [66]
    Здесь

    http://msdn2.microsoft.com/en-us/library/ms885202.aspx

    черным по белому нарисована логика вызовов DllMain с тем или иным резоном.

    С учетом же того, что вызовы DllMain конкретного модуля в контексте текущего процесса осуществляются системой синхронно, "феномен зависания" становится совершенно очевидным и понятным, даже без вникания во всякие там PEBы и TIBы.
  • Сергей М, (25.04.08 21:01) [67]
    ))
  • Loginov Dmitry © (25.04.08 21:12) [68]
    > ну нифига... У тебя все расчитано, что максимум будет создан
    > один поток.. Второй поток уже внесет несусветную суматоху.


    мне просто не требуется, чтобы в программе крутилось несколько однотипных потоков, поэтому выбрано такое решение. В других случаях будет выбрано другое решение. Кстати, после WaitForSingleObject() стоило бы выждать хотябы немного времени (например 50 / 100 мс), чтобы стать более уверенным, что функция потока уперлась в ExitThread() (а этот код уже выполняется не в нашей DLL-ке, а в kernel) и ожидает снятия блокировки, в этом случае выгрузка библиотеки уже точно ни на что не повлияет, и никаких AV не будет.

    > да с чего ты взял, что винда потоки срубает?!?! Винда финализирует
    > потоки не при FreeLibrary


    Вот срубает и все тут. Причем FreeLibrary() перед закрытием программы вызывается. В одном случае срубает, в другом - не срубает. Есть конечно подозрение, что где-то в системе лишний раз LoadLibrary() для моей библиотеки кто-то вызвал, но наврядли... Проверю на следующей неделе.


    > И чем они отличаются от потоков, созданных в другом месте
    > кода ?

    Потоковой функцией, код которой выгружается вместе с DLL-кой в том случае, если он принадлежит DLL-ке.
  • Пробегал2... (25.04.08 21:42) [69]
    Игорь Шевченко ©   (25.04.08 20:42) [64]
    Это всего лишь твое имхо. Ни больше, ни меньше


    ок, давайте по другому. Игорь, только честно - у вас были проекты, где поток создавался в коде DLL, а завершался в другом месте?

    P.S. Это я уже не говорю об использовании класса TThread, там уж как ни крути финализировать надо там же, где создаешь.
  • Игорь Шевченко © (25.04.08 22:50) [70]
    Пробегал2...   (25.04.08 21:42) [69]

    Я не единственный разработчик программного обеспечения на этом свете.
    И на слабо бери кого-нибудь другого.
  • Пробегал2... (25.04.08 23:40) [71]
    Игорь Шевченко ©   (25.04.08 22:50) [70]

    как я понимаю, ответ нет, ни в одном проекте вы так не делали.
    Что и требовалось доказать.
  • Игорь Шевченко © (26.04.08 00:13) [72]
    Пробегал2...   (25.04.08 23:40) [71]

    И на слабо бери кого-нибудь другого. Доказатель фигов
  • Пробегал2... (26.04.08 02:52) [73]
    ну хорошо. Я моих проектах никогда не было, чтобы поток создавался в DLL, а завершался в другой DLL или в самом приложении.
    И мне такой подход кажется нелогичным и путанным, когда DLL обязывает выполнять какие-то телодвижения кроме загрузки и выгрузки библиотеки.

    Да, это мое ИМХО. ну не согласны - и не согласны ;)
  • Игорь Шевченко © (26.04.08 11:02) [74]
    Пробегал2...   (26.04.08 02:52) [73]

    С точки зрения процесса, и основное приложения и DLL - это всего лишь части кода, связанные в единое адресное пространство (про различные менеджеры памяти или VMT для дельфийских классов в этом аксепте упоминать сейчас не будем, так как консепция потоков не зависит от используемого языка программирования). Таким образом, ничто не мешает потоку, начавшись в одной части кода. завершится абсолютно в другой.
    Система это делать позволяет.
    Более того, система даже позволяет создать поток в одном приложении, а завершать его в другом, используя функции CreateRemoteThread и TerminateThread

    Давайте все-таки различать - возможно/невозможно и удобно/неудобно
  • Котик Б (26.04.08 16:48) [75]
    Игорь, я Вами восхищаюсь :)
  • имя (26.04.08 20:28) [76]
    Удалено модератором
  • Экс-Оригинал (26.04.08 21:59) [77]
    Кто-нибудь может привести пример(свой, чужой - неважно),
    где бы в DLL создавался поток (BeginThread/TThread), затем DLL из приложения выгружалась бы, а поток продолжал работать?
  • Loginov Dmitry © (26.04.08 22:08) [78]
    > где бы в DLL создавался поток (BeginThread/TThread), затем
    > DLL из приложения выгружалась бы, а поток продолжал работать?


    На ум приходит только одно: потоковая функция расположена в другом модуле.
  • guav © (26.04.08 22:22) [79]

    > > где бы в DLL создавался поток (BeginThread/TThread), затем
    > > DLL из приложения выгружалась бы, а поток продолжал работать?
    > На ум приходит только одно: потоковая функция расположена
    > в другом модуле.


    Потоковая это только адрес начала потока, далее может быть переходы куда угодно. Легко представить себе начало потока в dll, затем продолжение в другой и вызов ExitThread уже оттуда. Можно даже и без ExitThread, обычным возвратом, просто переход в другой модуль не по call, а по jmp.
    Или так: в потоке создаются фиберы, и поток завершается в фибере созданном в другом модуле.
 
Конференция "Прочее" » Многопоточность и Delphi
Есть новые Нет новых   [134435   +35][b:0][p:0.001]