МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • Реферат: Потоки в Visual Basic

    Реферат: Потоки в Visual Basic

    С появлением оператора AddressOf, часть индустрии ПО стала ориентироваться на авторов, показывающих  как с использованием Visual Basic решать ранее невозможные задачи. Другая часть быстро охватила консультантов, помогающих пользователям, имеющим проблемы при решении таких задач.

    Проблема не в Visual Basic или в технологии. Проблема в том, что большинство авторов применяют одно и  тоже правило к AddressOf методикам, что большинство компаний по разработке ПО считают, что если Вы  должны что-то сделать, то Вы сможете. Идея о том, что применение самой новой и последней технологии  должно, по определению, быть самым лучшим решением проблемы, широко распространена в индустрии ПО.

    Эта идея неверна. Развертывание технологии должно управляться прежде всего проблемой, которую  необходимо решить решить, а не технологией, которую кто-то пробует Вам впарить;).  

    Очень плохо, что из-за того, что компании часто пренебрегают упоминанием об ограничениях и недостатках  их инструментальных средств, авторы иногда бывают не в состоянии обратить внимание читателей на  следствия некоторых методик, которые они описывают. И журналы и книги иногда пренебрегают своей  ответственностью, чтобы удостовериться, что практика программирования, которую они описывают, является  приемлемой.  

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

    Недавние статьи в Microsoft Systems Journal и Visual Basic Programmer's Journal представили программистам на  Visual Basic возможность использования функции API CreateThread, чтобы непосредственно поддерживать  многопоточный режим под Visual Basic. После этого, один читатель пожаловался, что моя книга Visual Basic  Programmer's Guide to the Win32 API является неполной, потому что я не описал в ней эту функцию и не  продемонстрировал эту технологию. Эта статья - частично является ответом этому читателю, и частично -  ответом на другие статьи, написанными на эту тему. Эта статья также является дополнением к главе 14 моей  книги "Разработка ActiveX компонент на Visual Basic 5.0" относительно новых возможностей, обеспечиваемых  Visual Basic 5.0 Service Pack 2.  

    Быстрый обзор Многопоточности 

    Если Вы уже хорошо разбираетесь в технологии многопоточного режима, то Вы можете пропустить этот  раздел и продолжать чтение с раздела, названного "Что нового в Service Pack 2."  

    Каждый, кто использует Windows, знает, что Windows способно делать больше чем одну вещь одновременно.  

    Может одновременно выполнять несколько программ, при одновременном проигрывании компакт-диска,  посылке факса и пересылке файлов. Каждый программист знает (или должен знать) что ЦЕНТРАЛЬНЫЙ  ПРОЦЕССОР компьютера может только выполнять одну команду одновременно (проигнорируем  существование многопроцессорных машин). Как единственный ЦЕНТРАЛЬНЫЙ ПРОЦЕССОР может  выполнять множество задач?  

    Это делается быстрым переключением между многими задачами. Операционная система содержит в памяти  все программы, которые запущены в настоящий момент. Это позволяет ЦЕНТРАЛЬНОМУ ПРОЦЕССОРУ  выполнять программы по очереди. Каждый раз происходит переключение между программами, при этом  меняется содержимое внутренних регистров, включая указатель команды и указатель вершины стека. Каждая из  таких "задач" называется потоком выполнения (thread of execution).  

    В простой многозадачной системе, каждая программа имеет емеет единственный поток. Это означает, что  ЦЕНТРАЛЬНЫЙ ПРОЦЕССОР начинает выполнение команд в начале программы и продолжает следуя  инструкциям в последовательности, определенной программой до тех пор, пока программа не завершается.  

    Скажем, программа имеет пять команд: B C D и E, которые выполняются последовательно (никаких  переходов нет в этом примере). Когда приложение имеет один поток, команды будут всегда выполнять в точно  том же самом порядке: A, B, C, D и E. Действительно, ЦЕНТРАЛЬНЫЙ ПРОЦЕССОР может потребовать  времени для выполнения других команд в других программах, но они не будут влиять на это приложение, если  не имеется конфликт над общими ресурсами системы, но это уже отдельная тема для разговора.  

    Продвинутая многопоточная операционная система типа Windows позволяет приложению выполнять  больше чем один поток одновременно. Скажем, команда D в нашем типовом приложении могла создать новый  поток, который стартовал командой B и далее выполнял последовательность команд C и E. Первый поток был  бы все еще A, B, C, D, E, но когда команда D выполнится, возникнет новый поток, который выполнит команды  бы B, C, E (здесь команды D уже не будет, иначе мы получим еще один поток).

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

    Это могло бы быть:

    Thread 1 A B C D E E

    Thread 2 B C

    Или так:  

    Thread 1 A B C D E  

    Thread 2 B C E  

    Или этак: 

    Thread 1 A B C D E 

    Thread 2 B C E   

    Другими словами, когда Вы начинаете новый поток выполнения в приложении, Вы никогда не можете  знать точный порядок, в котором команды в двух потоках выполнятся относительно друг друга. Два потока  полностью независимы.

    Почему - это проблема?  

    Имитатор Многопоточности

    Рассмотрим проект MTDemo:

    Проект содержит один модуль кода, в котором содержится две глобальных переменных:

    ' MTDemo - Multithreading Demo program

    ' Copyright © 1997 by Desaware Inc. All Rights Reserved

    Option Explicit

    Public GenericGlobalCounter As Long

    Public TotalIncrements As Long

    ' Этот проект содержит одну форму - frmMTDemo1, которая содержит

    ' следующий код:

    ' MTDemo - Multithreading Demo program

    ' Copyright © 1997 by Desaware Inc. All Rights Reserved

    Option Explicit

    Dim State As Integer 

    ' State = 0 - Idle 

    ' State = 1 - Loading existing value 

    ' State = 2 - Adding 1 to existing value 

    ' State = 3 - Storing existing value 

    ' State = 4 - Extra delay

    Dim Accumulator As Long

    Const OtherCodeDelay = 10

    Private Sub Command1_Click() 

    Dim f As New frmMTDemo1 

    f.Show

    End Sub

    Private Sub Form_Load() 

    Timer1.Interval = 750 + Rnd * 500

    End Sub

    Private Sub Timer1_Timer() 

    Static otherdelay& 

    Select Case State 

    Case 0 

    lblOperation = "Idle" 

    State = 1 

    Case 1 

    lblOperation = "Loading Acc" 

    Accumulator = GenericGlobalCounter 

    State = 2 

    Case 2 

    lblOperation = "Incrementing" 

    Accumulator = Accumulator + 1 

    State = 3 

    Case 3 

    lblOperation = "Storing" 

    GenericGlobalCounter = Accumulator 

    TotalIncrements = TotalIncrements + 1 

    State = 4 

    Case 4 

    lblOperation = "Generic Code" 

    If otherdelay >= OtherCodeDelay Then 

    State = 0 

    otherdelay = 0 

    Else 

    otherdelay = otherdelay + 1 

    End If 

    End Select 

    UpdateDisplay

    End Sub

    Public Sub UpdateDisplay() 

    lblGlobalCounter = Str$(GenericGlobalCounter) 

    lblAccumulator = Str$(Accumulator) 

    lblVerification = Str$(TotalIncrements)

    End Sub  

    Эта программа для моделирования многопоточного режима использует таймер и простой конечный  автомат. Переменная State описывает пять команд, которые эта программа выполняет. State = 0 - неактивное  состояние. State = 1 загружает локальную переменную глобальной переменной GenericGlobalCounter. State = 2  увеличивает на единицу локальную переменную. State = 3 запоминает результат в переменной  GenericGlobalCounter и увеличивает переменную TotalIncrements (которая считает количество приращений  переменной GenericGlobalCounter). State = 3 добавляет дополнительную задержку, представляющую собой  время, затраченное на выполнение других команд в программе.  

    Функция UpdateDisplay обновляет три метки на форме, которые показывают текущее значение переменной  GenericGlobalCounter, локального сумматора, и общего количества приращений.  

    Каждый сигнал таймера моделирует цикл ЦЕНТРАЛЬНОГО ПРОЦЕССОРА в текущем потоке. Если Вы  запустите программу, то увидете, что значение переменной GenericGlobalCounter будет всегда точно равно  переменной TotalIncrements, потому что переменная TotalIncrements показывает количество увеличений счетчика  GenericGlobalCounter потоком.  

    Но что случится, когда Вы нажимаете кнопку Command1 и запустите второй экземпляр формы? Эта новая  форма смоделирует второй поток.  

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

    Другими словами, переменная была увеличена дважды, но значение увеличилось только на единицу. Если Вы  запускаете несколько форм, то сразу заметите, что число приращений, представляемой переменной  TotalIncrements, растет намного быстрее, чем счетчик GenericGlobalCounter.  

    Что, если переменная представляет объектный счет блокировки - который следит, когда объект должен быть  освобожден? Что, если она представляет собой сигнал, который указывает, что ресурс находится в  использовании?  

    Такая проблема может привести к появлению ресурсов, постоянно недоступных в системе, к объекту,  блокируемому в памяти, или преждевременно освобожденному. Это может привести к сбоям приложения.  

    Этот пример был разработан, чтобы достаточно просто увидеть проблему, но попробуйте  поэкспериментировать со значением переменной OtherCodeDelay. Когда опасный код относительно небольшой  по сравнению со всей программой, проблемы появятся менее часто. Хотя это и звучит обнадеживающе, но  истина состоит в следующем. Проблемы Многопоточного режима могут быть чрезвычайно неустойчивы и их  трудно обнаружить. Это означает, что многопоточный режим требует осторожного подхода к проектированию  приложения.  

    Решение проблем Многопоточности

    Имеются два относительно простых способа избежать проблем многопоточного режима.

    Избегайте всеобщего использования глобальных переменных.

    Добавьте код синхронизации везде, где используются глобальные переменные.  

    Первый подход используется в основном в Visual Basic. Когда Вы включаете многопоточный режим в Visual

    Basic приложения, все глобальные переменные станут локальными для специфического потока. Это  свойственно способу, с которым Visual Basic выполняет apartment model threading - подробнее об этом позднее.  

    Первоначальный выпуск Visual Basic 5.0 позволял использовать многопоточность только в компонентах,  которые не имели никаких элементов пользовательского интерфейса. Так было потому что они не имели  безопасного потока управления формами. Например: когда Вы создаете форму в Visual Basic, VB дает ей имя  глобальной переменной (таким образом, если Вы имеете форму, именованную Form1, Вы можете  непосредственно обращаться к ее методам, используя Form1.метод вместо того, чтобы объявить отдельную  переменную формы). Этот тип глобальной переменной может вызывать проблемы многопоточного режима,  которые Вы видели ранее. Имелись несомненно другие проблемы внутри управления формами.  

    С service pack 2, управление формами Visual Basic было сделано безопасным потоком. Это говорит о том, что  каждый поток имеет собственную глобальную переменную для каждой формы, определенной в проекте.  

    Что нового в Service Pack 2 

    Сделав поток управления формами безопасным, Service pack 2 предоставил возможность с помощью Visual

    Basic создавать клиентские приложения, использующие многопоточный режим.

    Приложение должно быть определено как программа ActiveX Exe с установкой запуска из Sub Main:

    ' MTDemo2 - Multithreading demo program

    ' Copyright © 1997 by Desaware Inc. All Rights Reserved

    Option Explicit

    Declare Function FindWindow Lib "user32" Alias "FindWindowA" _

    (ByVal lpClassName As String, ByVal lpWindowName As String) _ 

    As Long

    Sub Main() 

    Dim f As frmMTDemo2 

    ' We need this because Main is called on each new thread 

    Dim hwnd As Long 

    hwnd = FindWindow(vbNullString, "Multithreading Demo2") 

    If hwnd = 0 Then 

    Set f = New frmMTDemo2 

    f.Show 

    Set f = Nothing 

    End If

    End Sub  

    Первый раз программа загружает и отображает основную форму приложения. Подпрограмма Main должна  выяснить, является ли это первым потоком приложения, поэтому этот код выполняется при старте каждого  потока. Вы не можете использовать глобальную переменную, чтобы это выяснить, потому что Visual Basic  apartment model хранит глобальные переменные специфическими для одиночного потока. В этом примере  используется функция API FindWindow, чтобы проверить, была ли загружена основная форма примера.

    Имеются другие способы выяснить, является ли это основным потоком, включая использование объектов  синхронизации системы - но это отдельная тема для разговора.  

    Многопоточный режим реализуется созданием объекта в новом потоке. Объект должен быть определен,  используя модуль класса. В этом случае, простой модуль класса определяется следующим образом:

    ' MTDemo2 - Multithreading demo program

    ' Copyright © 1997 by Desaware Inc. All Rights Reserved

    Option Explicit

    Private Sub Class_Initialize() 

    Dim f As New frmMTDemo2 

    f.Show 

    Set f = Nothing

    End Sub  

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

    ' MTDemo2 - Multithreading demo program

    ' Copyright © 1997 by Desaware Inc. All Rights Reserved

    Option Explicit

    Private Sub cmdLaunch1_Click() 

    Dim c As New clsMTDemo2 

    c.DisplayObjPtr Nothing

    End Sub

    Private Sub cmdLaunch2_Click() 

    Dim c As clsMTDemo2 

    Set c = CreateObject("MTDemo2.clsMTDemo2")

    End Sub

    Private Sub Form_Load() 

    lblThread.Caption = Str$(App.ThreadID)

    End Sub  

    Форма отображает идентификатор потока в метке на форме. Форма содержит две командные кнопки, одна из  которых использует оператор New, другая -использует оператор CreateObject.  

    Если Вы запустите программу внутри среды Visual Basic, то увидите, что формы всегда создаются в одном и  том же потоке. Это происходит, потому что среда Visual Basic поддерживает только одиночный поток. Если Вы  скомпилируете и запустите программу, то увидите, что подход, использующий CreateObject создает и  clsMTDemo2 и ее форму в новом потоке.  

    Почему многопоточность 

    Откуда вся суета относительно многопоточного режима, если он включает так много потенциальной  опасности? Потому что, в некоторых ситуациях, многопоточный режим может значительно улучшать  эффективность приложения. В некоторых случаях это может улучшать эффективность некоторых операций  синхронизации типа ожидания завершения приложения. Это позволяет сделать архитектуру приложения более  гибкой. Например, операция Add a long в форме MTDEMO2 со следующим кодом:

    Private Sub cmdLongOp_Click() 

    Dim l& 

    Dim s$ 

    For l = 1 To 1000000 

    s = Chr$(l And &H7F) 

    Next l

    End Sub  

    Запустите несколько экземпляров формы, используя кнопку cmdLaunch1. Когда Вы нажимаете на кнопку  cmdLongOp на любой из форм, то увидите, что это действие замораживает операции на всех других формах. Так  происходит, потому что все формы выполняются в одиночном потоке - и этот поток занят выполнением  длинного цикла. Если Вы запустите несколько экземпляров формы кнопкой cmdLaunch2 и нажимете кнопку  cmdLongOp на форму, то только эта форма будет заморожена - другие формы будут активными. Они  выполняются в собственных потоках, и длинный цикл будет выполняться только в собственном потоке.

    Конечно, в любом случае, Вы вероятно не должны размещать длительные операции такого типа в ваших  формах.

    Дальше краткое резюме, когда важен многопоточный режим:

    Сервер ActiveX EXE – без общих ресурсов.  

    Когда Вы имеете ActiveX EXE сервер, который Вы собираетесь совместно использовать среди   нескольких приложений, многопоточный режим предотвращает приложения от нежелательных   взаимодействий с друг другом. Если одно приложение выполняет длинную операцию на объекте в   однопоточном сервере, другие приложения будут вытеснены, т.е. будут ждать, когда освободится   сервер. Многопоточный режим рещает эту проблему. Однако, имеются случаи, где Вы можете   хотеть использовать ActiveX EXE сервер, чтобы регулировать доступ к общедоступнному ресурсу   (shared resource). Например, сервер stock quote, описанный в моей книге Developing ActiveX   Components. В этом случае сервер stock quote выполняется в одиночном потоке и который доступен   для всех приложений, использующих сервер по очереди.

    Многопоточный клиент – выполняемый как ActiveX EXE сервер 

    Простая форма этого подхода продемонстрирована в приложении MTDEMO2. Этот подход   используется, когда приложение поддерживает множественные окна, которые должны исходить из   одного приложения, но работать полностью независимо. Интернет-браузер - хороший пример   такого многопоточного клиента, где каждое окно выполняется в собственном потоке. Здесь следует   обратить внимание на то, что многопоточный режим не должен использоваться как замена для   хорошего событийно управляемого проекта.

    Многопоточные серверы DLL или EXE 

    В архитектуре клиент-сервер, многопоточный режим может увеличить эффективность, если Вы   имеете смесь длинных и коротких клиентских запросов. Будьте внимательным, хотя - если все ваши   клиентские запросы имеют подобную длину, многопоточный режим может фактически замедлять   среднее время ответа сервера! Никогда не принимайте на веру тот факт, что если ваш сервер   является многопоточным, то обязательно его эффективность увеличится.  

    Соглашение о потоках 

    Верите или нет, но все это было введением. Часть этого материала является обзором материала, который  описан в моей книге Developing ActiveX Components, другая часть материала описывает новую информацию для  service pack 2.  

    Теперь, позволите задавать вопрос, который имеет отношение к многопоточному режиму, использующему  COM (модель многокомпонентных объектов, на которой основаны не только все Visual Basic объекты, но и  другие windows приложения, использующие технологии OLE).

    Дано:  

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

    Страницы: 1, 2


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.