Latest web development tutorials

python3 Многопоточность

Несколько потоков одновременно выполняются аналогично ряду различных программ, многопоточные операции имеет следующие преимущества:

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

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

Каждый поток имеет свой собственный набор регистров процессора, называемый контекст нити, контекст нити отражает последний прогон состояния потока регистров процессора.

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

  • Тема может быть вытеснена (прерывистая).
  • В других потоков выполняются, поток может быть проведен в бездействии (также известный как сон) - это нить уступки.

Тема можно разделить на:

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

Python3 общая нить два модуля:

  • _thread
  • нарезания резьбы (рекомендуется)

Модуль резьбы был оставлен без присмотра. Пользователи могут использовать вместо того, чтобы модуль поточной. Так, в Python3 больше не может использовать модуль "нить". Для обеспечения совместимости, python3 поток будет переименовать "_thread".


Учим темы Python

Python потоки используются двумя способами: с функцией или классом, чтобы обернуть объект потока.

Функциональное: Вызов функции _thread модуль start_new_thread () для создания нового потока. Синтаксис выглядит следующим образом:

_thread.start_new_thread ( function, args[, kwargs] )

Параметр Описание:

  • функция - функция потока.
  • арг - параметры резьбы, передаваемые в функцию, он должен быть типом кортежа.
  • kwargs - необязательно.

Пример:

#!/usr/bin/python3

import _thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

# 创建两个线程
try:
   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print ("Error: 无法启动线程")

while 1:
   pass

Результаты выходных выше программы заключаются в следующем:

Thread-1: Wed Apr  6 11:36:31 2016
Thread-1: Wed Apr  6 11:36:33 2016
Thread-2: Wed Apr  6 11:36:33 2016
Thread-1: Wed Apr  6 11:36:35 2016
Thread-1: Wed Apr  6 11:36:37 2016
Thread-2: Wed Apr  6 11:36:37 2016
Thread-1: Wed Apr  6 11:36:39 2016
Thread-2: Wed Apr  6 11:36:41 2016
Thread-2: Wed Apr  6 11:36:45 2016
Thread-2: Wed Apr  6 11:36:49 2016

После выполнения вышеописанного процесса можно нажать Ctrl-C для выхода.


Многопоточность модуль

Python3 обеспечивают поддержку многопоточности через два стандартной библиотеки _thread и нарезание резьб.

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

Другие методы в дополнение к модулю поточной содержит модуль _thread все методы, но и обеспечить:

  • threading.currentThread (): Возвращает текущую переменную потока.
  • threading.enumerate (): Возвращает бегущая нить список содержит. Обращается запущен поток начал до конца, он не включает в себя нити перед началом и после окончания.
  • threading.activeCount (): Возвращает количество потоков, которые выполняются, и LEN (threading.enumerate ()) имеют один и тот же результат.

В дополнение к использованию методов, модуль нарезание резьбы также предоставляет класс Thread для обработки резьбы, класс резьбы предоставляет следующие методы:

  • запустить (): чтобы указать метод активных потоков.
  • начать (): начало потоков деятельности.

  • присоединиться ([время]): Подождите , пока поток не прерывается.Это блокирует вызывающий поток до метода потока присоединиться () называется подвеска - нормальный выход или бросить необработанное исключение - или дополнительный тайм-аута.
  • IsAlive (): Возвращает поток активен.
  • GetName (): Возвращает имя потока.
  • SetName (): Установить имя потока.

Используйте потоковую модуль для создания потока

Мы можем быть созданы непосредственно в наследство от threading.Thread новый подкласс, после того, как метод вызова запуска и инстанцирует (), чтобы начать новую тему, которую он вызывает метод выполнения потока ():

#!/usr/bin/python3

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")

Результаты выполнения выше программы следующим образом;

开始线程:Thread-1
开始线程:Thread-2
Thread-1: Wed Apr  6 11:46:46 2016
Thread-1: Wed Apr  6 11:46:47 2016
Thread-2: Wed Apr  6 11:46:47 2016
Thread-1: Wed Apr  6 11:46:48 2016
Thread-1: Wed Apr  6 11:46:49 2016
Thread-2: Wed Apr  6 11:46:49 2016
Thread-1: Wed Apr  6 11:46:50 2016
退出线程:Thread-1
Thread-2: Wed Apr  6 11:46:51 2016
Thread-2: Wed Apr  6 11:46:53 2016
Thread-2: Wed Apr  6 11:46:55 2016
退出线程:Thread-2
退出主线程

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

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

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

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

Рассмотрим случай: список всех элементов равны нулю, нить "набор" от задней стенки к передней всех элементов в одно целое, и нить "печать" спереди назад, отвечающий за чтение списка и печати.

Затем нить может быть "установить" начала меняться, когда "печать" нить это напечатать список, было бы половина выход половины 0, что данные не будут синхронизированы. Чтобы избежать такой ситуации, мы вводим понятие замка.

Замок имеет два состояния - заблокировать и разблокировать. Всякий раз, когда поток, такой как "набор" для доступа к общим данным, вы должны сначала получить блокировку, если у вас уже есть другой поток, например, как "печать", чтобы получить заперт, то пусть нить "набор" пауза, которая является синхронным блокирование; дожидаемся нити " печать "доступ завершается, после выхода замка, пусть нить" набор ", чтобы продолжить.

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

Пример:

#!/usr/bin/python3

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开启线程: " + self.name)
        # 获取锁,用于线程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁,开启下一个线程
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

Вышеприведенная программа, выход:

开启线程: Thread-1
开启线程: Thread-2
Thread-1: Wed Apr  6 11:52:57 2016
Thread-1: Wed Apr  6 11:52:58 2016
Thread-1: Wed Apr  6 11:52:59 2016
Thread-2: Wed Apr  6 11:53:01 2016
Thread-2: Wed Apr  6 11:53:03 2016
Thread-2: Wed Apr  6 11:53:05 2016
退出主线程

очереди приоритета потока (Очередь)

Модуль Queue Python обеспечивает синхронизацию, поточно-классы очередей, в том числе FIFO (первый в первом из очереди) очереди, LIFO (последний, первым обслужен) очереди LifoQueue и очереди приоритета PriorityQueue.

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

Модуль Queue часто используемые методы:

  • Queue.qsize () возвращает размер очереди
  • Queue.empty (), если очередь пуста, возвращает True, False и наоборот
  • Queue.full () Если очередь заполнена, возвращение True, False и наоборот
  • В соответствии с размером и MAXSIZE Queue.full
  • Queue.get ([блок [, тайм-аут]]) Возвращает очереди, время ожидания тайм-аута
  • Queue.get_nowait () довольно Queue.get (False)
  • Queue.put (пункт) очереди записи, тайм-аут Время ожидания
  • Queue.put_nowait (пункт) весьма Queue.put (пункт, False)
  • Queue.task_done () после завершения работы, Queue.task_done () функция посылает сигнал к задаче была завершена очередь
  • Queue.join () на самом деле означает, пока очередь не опустеет, а затем выполнять другие операции

Пример:

#!/usr/bin/python3

import queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print ("开启线程:" + self.name)
        process_data(self.name, self.q)
        print ("退出线程:" + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

Результаты выше программы:

开启线程:Thread-1
开启线程:Thread-2
开启线程:Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
退出线程:Thread-3
退出线程:Thread-2
退出线程:Thread-1
退出主线程