Latest web development tutorials

Python3 Wielowątkowość

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.

Gwint może być podzielone na:

  • wątki jądra: jądro systemu operacyjnego tworzone i niszczone.
  • Nici użytkowników: Wsparcie jądra i nie wymaga programu użytkownika realizowany wątek.

Python3 wspólny wątek dwa moduły:

  • _thread
  • gwintowania (zalecane)

Moduł wątek został porzucony. Użytkownicy mogą korzystać z modułu zamiast wątków. Tak więc, w Python3 nie mogą już korzystać z modułu "GW". Dla kompatybilności, Python3 wątek będzie zmienić nazwę "_thread".


Zacznij naukę Pythona wątki

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

Funkcjonalne: Call _thread moduł funkcyjny 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/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

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

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

Po wykonaniu powyższych czynności można naciśnij Ctrl-C, aby zamknąć.


moduł Threading

Python3 zapewnić wsparcie dla gwintowania przez dwa standardowe _thread biblioteki i gwintowania.

_thread dostarcza niskiego poziomu oryginalnego wątku i prostą blokadę, to jest w porównaniu do modułu funkcja gwintowania jest wciąż stosunkowo ograniczona.

Inne sposoby, oprócz modułu gwintowania zawiera moduł _thread wszystkie metody, ale również w celu zapewnienia:

  • 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.

Za pomocą modułu wątków utworzyć wątku

Możemy być tworzone bezpośrednio dziedziczona z threading.Thread nową podklasę, po metody startu oraz instancję (wywołania), aby rozpocząć nowy wątek, który wywołuje metodę uruchomić wątku ():

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

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

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

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

Powyższy program, wyjście jest:

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

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 wielowątkowej, można skorzystać z kolejki, 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/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 ("退出主线程")

Wyniki powyższego programu:

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