Latest web development tutorials

python3 Multithreading

Più thread eseguiti contemporaneamente è simile a una serie di programmi diversi, operazione multithread presenta i seguenti vantaggi:

  • Utilizzando thread possono occupare lungo programma nel compito in secondo piano da affrontare.
  • L'interfaccia utente può essere più attraente, così per esempio l'utente fa clic su un pulsante per attivare delle gestione degli eventi, è possibile pop una barra di avanzamento per mostrare lo stato di avanzamento del processo di
  • velocità di marcia potrebbe accelerare
  • Su realizzate alcune operazioni, come ad esempio in attesa di input da parte dell'utente, del documento di alfabetizzazione e di rete per inviare e ricevere dati, il filo è più utile. In questo caso, siamo in grado di liberare alcune risorse preziose, come l'utilizzo della memoria e così via.

Thread nel processo di attuazione e il processo è diverso. Ciascuno ha un thread separato esecuzione ingresso, sequenza di uscita e le procedure per l'attuazione dell'ordine. Ma il filo non è in grado di eseguire autonomamente, deve esistere seconda dell'applicazione, fornendo più thread di esecuzione controllati dall'applicazione.

Ogni thread ha il proprio set di registri della CPU, chiamato il contesto del thread, il contesto filo riflette l'ultima esecuzione dello stato filo registro della CPU.

puntatore all'istruzione e puntatore stack di registri sono i due più importanti registri di contesto filo, il filo sempre viene eseguito nel contesto del processo, questi indirizzi sono usati per marcare il processo che possiede il filo di spazio di indirizzi di memoria.

  • Discussione può essere preempted (interrotto).
  • In altri thread sono in esecuzione, il thread può essere tenuta in sospeso (noto anche come il sonno) - questo è il filo di concessioni.

Discussione possono essere suddivisi in:

  • thread del kernel: il kernel del sistema operativo creato e distrutto.
  • thread utente: supporto nel kernel e non richiede il programma utente implementate thread.

Python3 filo conduttore di due moduli:

  • _thread
  • threading (consigliato)

Modulo thread è stato abbandonato. Gli utenti possono utilizzare al posto del modulo threading. Così, in python3 non può più utilizzare il modulo "filo". Per la compatibilità, filo python3 rinominerà "_thread".


Iniziare ad imparare le discussioni Python

le discussioni di pitone utilizzata in due modi: con una funzione o di classe per avvolgere l'oggetto thread.

Funzionale: Call funzione _thread modulo start_new_thread () per generare un nuovo thread. La sintassi è la seguente:

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

Descrizione Parametro:

  • - Funzione thread.
  • args - i parametri di filettatura passati alla funzione, che deve essere un tipo tupla.
  • kwargs - opzionali.

esempio:

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

I risultati di output sopra programma sono i seguenti:

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

Dopo aver eseguito il processo di cui sopra può premere Ctrl-C per uscire.


modulo threading

Python3 fornisce il supporto per la filettatura attraverso due _thread libreria standard e filettatura.

_thread fornisce un basso livello, il thread originale e di una serratura semplice, viene confrontato con il modulo funzionale filettatura è ancora relativamente limitata.

Altri metodi, oltre a modulo threading contiene moduli _thread tutti i metodi, ma anche per fornire:

  • threading.currentThread (): restituisce la variabile thread corrente.
  • threading.enumerate (): restituisce un elenco filo conduttore contiene. Si riferisce in esecuzione filo iniziata prima della fine, non include il filo prima di iniziare e dopo la cessazione.
  • threading.activeCount (): restituisce il numero di thread in esecuzione, e len (threading.enumerate ()) hanno lo stesso risultato.

Oltre all'uso di metodi, modulo threading fornisce anche una classe Thread per gestire il filo, classe Thread fornisce i seguenti metodi:

  • run (): per indicare il metodo di thread attivi.
  • start (): avviare l'attività thread.

  • join ([ora]): Attendere che viene interrotta il filo.Questo blocca il thread chiamante fino a quando il metodo join () del thread si chiama sospensione - uscita normale o un'eccezione non gestita - o timeout opzionale si verifica.
  • isAlive (): restituisce il thread è attiva.
  • getName (): restituisce il nome del thread.
  • setName (): Impostare il nome thread.

Utilizzare modulo threading per creare un filo

Ci possono essere creati direttamente ereditato da threading.Thread una nuova sotto-classe, dopo il metodo di inizio e di istanziare (chiamata) per avviare un nuovo thread, che si chiama il metodo run del thread ():

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

I risultati di esecuzione sopra programma sono i seguenti;

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

sincronizzazione dei thread

Se più thread di una modifica di dati comune, potrebbero verificarsi risultati imprevedibili, al fine di assicurare l'accuratezza dei dati, abbiamo bisogno di sincronizzare più thread.

oggetto filo con il blocco e RLOCK può realizzare una semplice sincronizzazione dei thread, i due oggetti hanno metodi di acquisire e metodi di rilascio, per chi ha bisogno ciascuno dei quali permette solo uno dei dati di funzionamento del filo, può essere messo in funzione acquisire e rilasciare i metodi della stanza. Come segue:

Multithreading vantaggio è che può eseguire contemporaneamente più attività (almeno si sente come questo). Ma quando le discussioni hanno bisogno di condividere i dati, non ci possono essere problemi di sincronizzazione dei dati.

Si consideri un caso: un elenco di tutti gli elementi sono pari a zero, il thread "set" da dietro in avanti tutti gli elementi in un unico, e la "stampa" filo da davanti a dietro responsabile della lettura della lista e stampa.

Quindi, il filo potrebbe essere "set" inizia a cambiare quando la "stampa" filo per stampare una lista, sarebbe metà della produzione di mezzo 0, che è il dato non è sincronizzato. Per evitare questa situazione, si introduce il concetto della serratura.

Blocco ha due stati - bloccato e sbloccato. Ogni volta che un filo, come "set" per accedere ai dati condivisi, è necessario prima acquisire il blocco, se si dispone già di un altro thread, come ad esempio "stampa" per ottenere bloccato, poi lasciare il filo "set" di pausa, che è il blocco sincrono, attendere che il filo " stampare "l'accesso è completata, dopo il rilascio della serratura, lasciare che il filo" set "per continuare.

Dopo questo processo, quando si stampa un elenco di tutti gli output 0 o 1 uscita completa, non appare più la metà imbarazzo 0 1 mezza.

esempio:

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

Il programma precedente, l'uscita è:

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

coda di priorità del thread (coda)

Modulo Coda di Python fornisce la sincronizzazione, le classi di coda thread-safe, tra cui FIFO (First In First Out) della coda della coda, LIFO (last in, first out) coda LifoQueue, e coda di priorità CodaConPriorita.

Queste code vengono implementate bloccaggio primitive possono essere utilizzati direttamente in un multithread, è possibile utilizzare la coda per ottenere la sincronizzazione tra i thread.

modulo coda metodi comunemente usati:

  • Queue.qsize () restituisce la dimensione della coda
  • Queue.empty () se la coda è vuota, restituisce True, False e viceversa
  • Queue.full () Se la coda è piena, tornare True, False e viceversa
  • Corrispondente al formato e MAXSIZE Queue.full
  • Queue.get ([blocco [, timeout]]) Ottiene la coda, timeout tempo di attesa
  • Queue.get_nowait () piuttosto Queue.get (Falso)
  • Queue.put (voce) coda di scrittura, timeout tempo di attesa
  • Queue.put_nowait (voce) piuttosto Queue.put (voce, False)
  • Queue.task_done () dopo il completamento di un lavoro, Queue.task_done () funzione invia un segnale al compito è stato completato coda
  • Queue.join () significa veramente fino a quando la coda è vuota, quindi eseguire altre operazioni

esempio:

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

I risultati del programma di cui sopra:

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