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