Latest web development tutorials

Python Multithreaded

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

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

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

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

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

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

Учим темы Python

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

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

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

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

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

Пример:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

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: unable to start thread"

while 1:
   pass

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

Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009

Конец нити, как правило, полагаются на естественный конец функции потока, также вызвать функцию thread.exit нить (), он бросает исключение SystemExit, достичь цели выхода нити.


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

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

Другой модуль методы резьбы обеспечивает:

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

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

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

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

Использование модуля Threading для создания темы

Использование модуля Threading для создания потока, непосредственно унаследованный от threading.Thread, а затем переопределить __init__ метод и запустить методы:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

exitFlag = 0

class myThread (threading.Thread):   #继承父类threading.Thread
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):                   #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            thread.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()

print "Exiting Main Thread"

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

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2

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

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

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

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

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

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

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

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

Пример:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

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 "Starting " + self.name
       # 获得锁,成功获得锁定后返回True
       # 可选的timeout参数不填时将一直阻塞直到获得锁定
       # 否则超时后将返回False
        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 "Exiting Main Thread"

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

Модуль 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/python
# -*- coding: UTF-8 -*-

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 "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + 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 "Exiting Main Thread"

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

Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread