Latest web development tutorials

python3 Multithreading

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.

Linha pode ser dividida em:

  • threads do kernel: o kernel do sistema operacional criado e destruído.
  • threads do usuário: o suporte do kernel e não exige que o programa do usuário implementado discussão.

Python3 linha comum dois módulos:

  • _thread
  • Threading (recomendado)

módulo de rosca foi abandonado. Os usuários podem usar o módulo de threading em seu lugar. Assim, em Python3 não pode mais usar o módulo de "thread". Para compatibilidade, linha Python3 irá renomear "_thread".


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: Chamar função _thread módulo 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/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

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

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

Depois de executar o processo acima pode pressionar ctrl-c para sair.


módulo de enfiar

Python3 fornecer suporte para enfiar através de dois _thread biblioteca padrão e rosqueamento.

_thread fornece um baixo nível, o segmento original e um bloqueio simples, ele é comparado com o módulo de função de enfiar é ainda relativamente limitada.

Outros métodos, para além do módulo de enfiar contém módulo _thread todos os métodos, mas também para proporcionar:

  • 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 o módulo de threading para criar um fio

Nós podem ser criados diretamente herdado da threading.Thread uma nova sub-classe, após o método de início e instanciar (call) para iniciar um novo tópico, o que ele chama de execução do segmento () método:

#!/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 ("退出主线程")

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

开始线程: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
退出主线程

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/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 ("退出主线程")

O programa acima, a saída é:

开启线程: 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
退出主线程

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 um de 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/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 ("退出主线程")

Os resultados do programa acima:

开启线程: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
退出主线程