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