Latest web development tutorials

Python wielowątkowe

Wiele wątków jednocześnie wykonywane są podobne do wielu różnych programów wielowątkowych operacja ma następujące zalety:

  • Korzystanie z wątków może zajmować długi program do wykonywania zadania w tle do czynienia.
  • Interfejs użytkownika może być bardziej atrakcyjna, więc na przykład użytkownik kliknie przycisk, aby wywołać niektóre obsługi zdarzeń, można pop pasek postępu, aby pokazać postęp procesu
  • Prowadzenie prędkości może przyspieszyć
  • Na niektórych realizowanych zadań, takich jak oczekiwanie na dane wejściowe użytkownika, czytania dokumentów i sieci do wysyłania i odbierania danych, wątek jest bardziej przydatna. W tym przypadku, można zwolnić cenne zasoby, takie jak wykorzystanie pamięci i tak dalej.

Wątki w procesie wdrażania i proces jest inny. Każdy posiada osobne wejście, wątkiem sekwencję wyjścia i procedury dotyczące realizacji zlecenia. Ale nici nie jest w stanie wykonać samodzielnie, musi istnieć w zależności od zastosowania, zapewniając wykonanie wielu wątków kontrolowane przez program.

Każdy wątek ma swój własny zestaw rejestrów procesora, zwany kontekst wątku kontekst wątku odzwierciedla ostatniego uruchomienia stanu wątku rejestru CPU.

Rejestry wskaźnik instrukcji i wskaźnik stosu są dwa najważniejsze rejestry kontekstu wątku, wątek zawsze zostanie uruchomiony w kontekście procesu, adresy te są wykorzystywane do oznaczania proces, który jest właścicielem nić przestrzeni adresowej pamięci.

  • Temat może być wywłaszczony (przerwany).
  • W innych wątków są uruchomione, nitka może być zawieszona (znany również jako snu) - jest to nić koncesji.

Zacznij naukę Pythona wątki

Nici Python używać na dwa sposoby: z funkcją lub klasa zawinąć obiekt gwintu.

Funkcjonalne: funkcja wywoływania Moduł gwintu start_new_thread (), aby wygenerować nowy wątek. Składnia jest następująca:

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

Parametr Opis:

  • Funkcja - Funkcja wątku.
  • args - parametry gwintu przekazywany do funkcji, musi być typu krotka.
  • kwargs - opcjonalnie.

Przykład:

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

Wyniki uzyskane powyżej programu są następujące:

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

Zakończenie nitki jest na ogół opiera się na naturalnym końca funkcji nici może także wywołać thread.exit funkcji wątku () rzuca SystemExit wyjątek osiągnięcia celu zamykania gwintu.


moduł Threading

Python zapewnia wsparcie dla gwintowania za pomocą dwóch standardowych bibliotek wątek i gwintowania. Gwint dostarcza niskiego poziomu oryginalnego wątku i prostą blokadę.

Inne metody wątku Moduł zapewnia:

  • threading.currentThread (): Zwraca aktualną zmienną gwintu.
  • threading.enumerate (): Zwraca uruchomiony zawiera lista wątków. Odnosi działa Temat rozpoczęty przed końcem, to nie obejmuje nić przed rozpoczęciem i po zakończeniu.
  • threading.activeCount (): Zwraca liczbę wątków, które są uruchomione, a len (threading.enumerate ()) mają ten sam rezultat.

Oprócz stosowania metod moduł gwintowania zapewnia również klasę wątku do obsługi wątku, klasa Thread udostępnia następujące metody:

  • run (): do wskazania metody aktywnych wątków.
  • start (): rozpoczęcie działalności gwintu.

  • join ([time]): Poczekaj, aż wątek jest przerwana.To blokuje wywołanie wątku dopóki metodzie wątku join () jest wywoływana zawieszenie - normalne opuszczenie lub rzucać nieobsługiwany wyjątek - lub opcjonalnie przekroczenie limitu czasu.
  • isAlive (): Zwraca wątek jest aktywny.
  • getName (): Zwraca nazwę wątku.
  • ustawNazwe (): Ustawia nazwę wątku.

Użyj Threading moduł do tworzenia tematów

Za pomocą modułu Threading stworzyć wątek, bezpośrednio dziedziczona z threading.Thread, a następnie zastąpić __init__ metody i sposoby uruchamiania:

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

Wyniki wykonania wyżej programu są następujące;

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

Synchronizacja wątek

Jeśli wiele wątków wspólnej modyfikacji danych, może przynieść nieoczekiwane skutki, w celu zapewnienia dokładności danych, musimy zsynchronizować wiele wątków.

Obiekt Temat pomocą zamka i Rlock może osiągnąć prostą synchronizację wątków, dwa obiekty są metody pozyskiwania i metody uwalniania dla tych, którzy potrzebują każdy pozwala tylko jeden danych operacyjnych nici, może być umieszczony w operacji nabywać i zwolnij Metody pokój. W następujący sposób:

Wielowątkowa zaletą jest to, że może jednocześnie wykonywać wiele zadań (przynajmniej czuje się tego). Ale kiedy gwinty muszą udostępniać dane, nie może być żadnych problemów z synchronizacją danych.

Rozważmy przypadek: lista wszystkich elementów są zerowe, wątek "zestaw" od tyłu do przodu wszystkich elementów w jedną całość, a nić "print" od przodu do tyłu za czytanie listy i drukować.

Następnie nić może być "ustawiony" zaczął się zmieniać, gdy wątek "print", aby wydrukować listę, to byłoby pół wyjście pół 0, co jest dane nie są zsynchronizowane. Aby uniknąć takiej sytuacji, wprowadzamy pojęcie zamka.

Blokada ma dwa stany - zablokowane i odblokowane. Ilekroć wątku takich jak "set", aby uzyskać dostęp do udostępnionych danych, należy najpierw uzyskać blokadę, jeśli masz już inny wątek, takie jak "print", aby uzyskać zamknięty, pozwól wątek "set" pauza, która jest synchroniczna blokowanie; poczekać do wątku " wydrukować "dostęp jest zakończona, po zwolnieniu blokady, niech wątek" sET ", aby kontynuować.

Po zakończeniu tego procesu, kiedy wydrukować listę wszystkich wyjściu 0 lub 1 pełną mocą, nie pojawia się już pol zakłopotanie 0 1 pół.

Przykład:

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

Priorytet wątku kolejki (Queue)

Moduł Queue Pythona zapewnia synchronizacji, zajęcia kolejki bezpieczny wątku, w tym FIFO (First In First Out) kolejki kolejki LIFO (ostatnie weszło, pierwsze wyszło), a kolejki LifoQueue priorytet kolejki kolejka priorytetowa. Kolejki te są realizowane blokujące prymitywy może być stosowany bezpośrednio w wielu wątkach. Można użyć kolejkę, aby osiągnąć synchronizację między wątkami.

Moduł Queue powszechnie stosowane metody:

  • Queue.qsize () zwraca rozmiar kolejki
  • Queue.empty (), jeśli kolejka jest pusta, zwraca true, false i vice versa
  • Queue.full () Jeśli kolejka jest pełna, powrót true, false i odwrotnie
  • Odpowiednio do wielkości i MAXSIZE Queue.full
  • Queue.get ([Blok [, czas oczekiwania]]) Pobiera kolejce, timeout, czas oczekiwania
  • Queue.get_nowait () raczej Queue.get (fałsz)
  • Queue.put (pozycja) zapisu kolejki, czas oczekiwania Czas oczekiwania
  • Queue.put_nowait (pozycja) dość Queue.put (pozycja, False)
  • Queue.task_done () po zakończeniu pracy, Queue.task_done () Funkcja wysyła sygnał do tego zadania została zakończona kolejkę
  • Queue.join () naprawdę znaczy dopóki kolejka jest pusta, a następnie wykonywać inne operacje

Przykład:

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

Wyniki powyższego programu:

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