Latest web development tutorials

Python Multithreaded

Vários segmentos executadas simultaneamente é semelhante a um certo número de diferentes programas, a operação de vários segmentos tem as seguintes vantagens:

  • Usando tópicos podem ocupar programa longo na tarefa em segundo plano para lidar com eles.
  • A interface do usuário pode ser mais atraente, assim, por exemplo o usuário clica em um botão para acionar alguns manipulação de eventos, você pode pop uma barra de progresso para mostrar o progresso do processo de
  • Correndo velocidade poderia acelerar
  • Em realizadas algumas tarefas, como à espera de entrada do usuário, literacia documental e de rede para enviar e receber dados, o fio é mais útil. Neste caso, podemos liberar alguns recursos valiosos, tais como uso de memória e assim por diante.

Threads no processo de implementação e o processo é diferente. Cada um tem um segmento separado em execução de entrada, saída e sequência de procedimentos para a execução da ordem. Mas a discussão não é capaz de executar de forma independente, ele deve existir de acordo com a aplicação, oferecendo múltiplas threads de execução controlados pela aplicação.

Cada segmento tem seu próprio conjunto de registros de CPU, chamado de contexto do segmento, o contexto do segmento reflete a última corrida do estado do segmento registo CPU.

ponteiro de instrução e ponteiro de pilha registros são os dois mais importantes registros contexto segmento, o segmento sempre é executado no contexto do processo, estes endereços são usados ​​para marcar o processo que possui o segmento do espaço de endereços de memória.

  • Thread pode ser apropriado (interrompido).
  • Em outras threads estão em execução, o fio pode ser suspenso (também conhecido como sono) - este é o segmento de concessões.

Começar a aprender tópicos Python

tópicos Python usado de duas maneiras: com uma função ou classe para embrulhar o objeto de discussão.

Funcional: a função chamando módulo de rosca start_new_thread () para gerar um novo segmento. A sintaxe é a seguinte:

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

Parâmetro Descrição:

  • função - função thread.
  • args - os parâmetros da linha passados ​​para a função, ele deve ser um tipo tupla.
  • kwargs - opcionais.

exemplo:

#!/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

Os resultados de saída do programa acima são como se segue:

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

A ponta da linha é geralmente contam com o fim natural da função de rosca; também pode ligar thread.exit função thread (), ele lança exceção SystemExit, atingir o objectivo de sair de discussão.


módulo de enfiar

Python fornece suporte para enfiar através de duas bibliotecas padrão rosca e rosqueamento. fio fornece um nível baixo, o segmento original e um bloqueio simples.

Outro módulo de métodos de discussão fornece:

  • threading.currentThread (): Retorna a variável de segmento atual.
  • threading.enumerate (): Retorna uma lista de discussão em execução contém. Refere-se a executar linha começada antes do fim, ele não inclui o fio antes de começar e depois da rescisão.
  • threading.activeCount (): Retorna o número de threads que estão em execução, e len (threading.enumerate ()) têm o mesmo resultado.

Além do uso de métodos, módulo de enfiamento também fornece uma classe de rosca para lidar com o fio, classe Thread fornece os seguintes métodos:

  • run (): para indicar o método de linhas ativas.
  • start (): iniciar a atividade de discussão.

  • join ([tempo]): Espere até que o segmento é abortada.Isto bloqueia o segmento de chamada até que o método do segmento join () é chamado de suspensão - saída normal ou lançar uma exceção não tratada - ou tempo limite opcional ocorre.
  • isAlive (): Retorna o fio está ativo.
  • getName (): Retorna o nome de discussão.
  • setName (): Definir o nome da lista de discussão.

Use Módulo de Threading para criar tópicos

Use o módulo threading para criar um fio, diretamente herdado da threading.Thread, em seguida, substituir __init__ método e executar métodos:

#!/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"

Os resultados da execução do programa acima são as seguintes;

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

Sincronização Tópico

Se, resultados imprevisíveis podem ocorrer vários segmentos de uma modificação de dados comum, a fim de garantir a precisão dos dados, é preciso sincronizar vários segmentos.

Thread objeto usando o bloqueio e RLOCK pode conseguir uma sincronização de thread simples, os dois objetos têm métodos de adquirir e métodos de liberação, para aqueles que precisam cada permitindo que apenas um dos dados operacionais da linha, ele pode ser colocado em adquirir a operação e liberar métodos da quarto. Como se segue:

Multithreading vantagem é que ele pode ser executado simultaneamente múltiplas tarefas (pelo menos se sente assim). Mas quando tópicos precisam compartilhar dados, pode não haver problemas de sincronização de dados.

Considere um caso: uma lista de todos os elementos são zero, o segmento "set" de trás para a frente todos os elementos em um, e o segmento "print" da frente para trás encarregado de ler a lista e imprimir.

Em seguida, o fio pode ser "set" começou a mudar quando o "print" thread-la para imprimir uma lista, seria metade da produção de meio 0, que é os dados não são sincronizados. Para evitar essa situação, introduzimos o conceito da fechadura.

Bloqueio tem dois estados - bloqueado e desbloqueado. Sempre que um fio, como "set" para acessar os dados compartilhados, você deve primeiro obter o bloqueio, se você já tem outro segmento, tais como "print" para se ver preso, em seguida, deixar o segmento "set" pausa, que é bloqueio síncrona; aguarde até que a thread " imprimir "o acesso é concluída, após a liberação do bloqueio, deixe o fio" set "para continuar.

Após este processo, quando você imprime uma lista de todas as saídas 0 ou 1 saída total, não aparece mais de metade constrangimento 0 1 metade.

exemplo:

#!/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"

fila de prioridade thread (Fila)

módulo da fila de Python fornece sincronização, classes de fila de thread-safe, incluindo FIFO (first in first out) Queue fila, LIFO (last in, first out) LifoQueue fila e PriorityQueue fila de prioridade. Essas filas são implementados bloqueio primitivas pode ser usado diretamente em vários segmentos. Você pode usar a fila para conseguir a sincronização entre threads.

módulo fila de métodos comumente utilizados:

  • Queue.qsize () retorna o tamanho da fila
  • Queue.empty () se a fila está vazia, retorna True, False e vice-versa
  • Queue.full () Se a fila estiver cheia, retornar True, False e vice-versa
  • Correspondente ao tamanho e maxsize Queue.full
  • Queue.get ([bloco [, timeout]]) Obtém a fila, tempo de timeout esperando
  • Queue.get_nowait () em vez Queue.get (Falso)
  • Queue.put (item) fila de gravação, o tempo limite de tempo de espera
  • Queue.put_nowait (item) bastante Queue.put (item, False)
  • Queue.task_done () após a realização de uma obra, Queue.task_done () função envia um sinal para a tarefa foi realizada fila
  • Queue.join () realmente significa até que a fila está vazia, então executar outras operações

exemplo:

#!/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"

Os resultados do programa acima:

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