Потоки Введение в Visual Basic

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

Определение темы

Поток - это единый последовательный поток управления.

Некоторые классификаторы:

  • Поток - это «путь выполнения» в этом теле кода.
  • Потоки разделяют память, поэтому они должны взаимодействовать для получения правильного результата.
  • Поток имеет специфичные для потока данные, такие как регистры, указатель стека и программный счетчик.
  • instagram viewer
  • Процесс - это единое тело кода, которое может иметь много потоков, но оно имеет как минимум один и имеет один контекст (адресное пространство).

Это вещи уровня сборки, но это то, с чем вы начинаете думать, когда начинаете думать о потоках.

Многопоточность против многопроцессорная обработка

Многопоточность это не то же самое, что многоядерная параллельная обработка, но многопоточность и многопроцессорность работают вместе. Большинство современных ПК имеют процессоры, которые имеют как минимум два ядра, а обычные домашние машины иногда имеют до восьми ядер. Каждое ядро ​​представляет собой отдельный процессор, способный запускать программы самостоятельно. Вы получаете повышение производительности, когда ОС назначает разные процессы разным ядрам. Использование нескольких потоков и нескольких процессоров для еще большей производительности называется параллелизмом на уровне потоков.

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

Практика безопасности нитей

Многопоточный код часто требует сложной координации потоков. Часто встречаются тонкие и трудно обнаруживаемые ошибки, поскольку разные потоки часто должны совместно использовать одни и те же данные, поэтому один поток может изменять данные, когда другой этого не ожидает. Общий термин для этой проблемы - «состояние гонки». Другими словами, два потока могут вступить в «гонку» для обновления одних и тех же данных, и результат может отличаться в зависимости от того, какой поток «выиграл». В качестве тривиального примера, предположим, что вы кодируете цикл:

Если счетчик цикла «I» неожиданно пропустит число 7 и перейдет с 6 на 8 - но только в течение некоторого времени - это будет иметь катастрофические последствия для того, что делает цикл. Предотвращение подобных проблем называется безопасностью потоков. Если программе требуется результат одной операции в более поздней операции, то для этого может оказаться невозможным кодирование параллельных процессов или потоков.

Основные многопоточные операции

Пришло время отодвинуть этот предупредительный разговор на задний план и написать несколько многопоточных кодов. Эта статья использует консольное приложение для простоты прямо сейчас. Если вы хотите продолжить, запустите Visual Studio с новым проектом консольного приложения.

Основным пространством имен, используемым для многопоточности, является Система. Пространство имен Threading и класс Thread будут создавать, запускать и останавливать новые потоки. В приведенном ниже примере обратите внимание, что TestMultiThreading является делегатом. То есть вы должны использовать имя метода, который может вызвать метод Thread.

В этом приложении мы могли бы выполнить второй Sub, просто вызвав его:

Это бы запустило все приложение в серийном режиме. Первый приведенный выше пример кода запускает подпрограмму TestMultiThreading и затем продолжается.

Пример рекурсивного алгоритма

Вот многопоточное приложение, включающее вычисление перестановок массива с использованием рекурсивного алгоритма. Не весь код показан здесь. Переставляемый массив символов - это просто «1», «2», «3», «4» и «5». Вот соответствующая часть кода.

Обратите внимание, что есть два способа вызвать подпрограмму Permute (оба закомментированы в коде выше). Один запускает поток, а другой вызывает его напрямую. Если вы позвоните прямо, вы получите:

Тем не менее, если вы запускаете поток и запускаете подпрограмму Permute, вы получаете:

Это ясно показывает, что по крайней мере одна перестановка генерируется, затем основная подпрограмма перемещается вперед и завершается, отображая «Законченная основная», в то время как остальные перестановки генерируются. Поскольку отображение происходит от второго подпункта, называемого подпрограммой Permute, вы также знаете, что это часть нового потока. Это иллюстрирует концепцию, согласно которой поток является «путем выполнения», как упоминалось ранее.

Пример состояния гонки

В первой части этой статьи упоминается состояние гонки. Вот пример, который показывает это непосредственно:

Непосредственное окно показало этот результат в одном испытании. Другие испытания были другими. Это суть состояния гонки.