Поделиться через


Синхронизация потоков

Обновлен: Ноябрь 2007

При написании многопотокового приложения может понадобиться синхронизация отдельных потоков с другими частями программы. Синхронизация является компромиссом между неструктурированной природой многопотокового программирования и структурированным порядком синхронной обработки.

Синхронизация используется в следующих случаях.

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

    либо

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

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

Алгоритмы синхронизации

Существуют два подхода к синхронизации — опрос и использование объектов синхронизации. См. раздел Дополнительные способы синхронизации для получения дополнительных сведений об объектах синхронизации.

Опрос

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

Например, чтобы выяснить, завершил ли работу поток, можно использовать при опросе свойство IsAlive. Это свойство следует использовать с осторожностью, поскольку само по себе существование потока не означает, что он выполняется.

Можно использовать свойство потока ThreadState для получения более подробных сведений о состоянии потока. Поскольку потоки могут быть в более чем одном состоянии в любой момент времени, значение, хранящееся в ThreadState, может быть сочетанием значений перечисления System.Threading.ThreadState. Поэтому при опросе следует тщательно проверять все состояния потока, имеющие отношение к решаемой задаче. Например, если состояние потока показывает, что поток не Running, возможно, его работа завершена. С другой стороны, поток может быть приостановлен или находиться в режиме ожидания.

Ожидание завершения работы потока

Метод Thread.Join позволяет определить, завершена ли работа потока, перед началом выполнения следующей задачи. Метод Join ожидает завершения работы потока в течение заданного промежутка времени. Если поток завершается до истечения времени ожидания, метод Join возвращает True; в противном случае он возвращает False.

Нетрудно заметить, что при опросе приходится жертвовать многими преимуществами многопоточности в обмен на возможность управления порядком выполнения потоков. Из-за своей неэффективности опрос обычно не рекомендуется к применению. Более рациональный подход — использование метода Join для управления потоками. Метод Join заставляет вызывающую процедуру ожидать, пока работа потока не завершится или пока не истечет время ожидания вызова, если оно задано. Название "join" (объединить) основано на трактовке создания нового потока как разветвления на пути выполнения. Метод Join используется для объединения различных путей выполнения обратно в один поток.

Установка и соединение потоков

Рисунок 1. Работа с потоками

Необходимо прояснить один момент: обращение к методу Join — это синхронный или блокирующий вызов. При вызове метода Join или одного из методов ожидания дескриптора ожидания вызывающая процедура останавливается и ждет сигнала о завершении работы потока.

Sub JoinThreads()
    Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)
    Thread1.Start()
    Thread1.Join()      ' Wait for the thread to finish.
    MsgBox("Thread is done")
End Sub
Sub SomeTask()
    ' Insert code to perform a task here.
End Sub

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

См. также

Основные понятия

Дополнительные возможности управления многопоточностью в Visual Basic

Параметры и возвращаемые значения для многопоточных процедур

Другие ресурсы

Многопотоковость в Visual Basic