Latest web development tutorials

Python multithreaded

Beberapa thread secara bersamaan dijalankan mirip dengan sejumlah program yang berbeda, operasi multithreaded memiliki keuntungan sebagai berikut:

  • Menggunakan benang dapat menempati Program panjang dalam tugas ke latar belakang untuk menangani.
  • Antarmuka pengguna mungkin lebih menarik, jadi misalnya pengguna mengklik tombol untuk memicu beberapa peristiwa penanganan, Anda dapat pop progress bar untuk menunjukkan kemajuan proses
  • Kecepatan lari bisa mempercepat
  • Pada menyadari beberapa tugas, seperti menunggu input pengguna, melek dokumen dan jaringan untuk mengirim dan menerima data, benang lebih berguna. Dalam hal ini, kita dapat membebaskan beberapa sumber daya berharga, seperti penggunaan memori dan sebagainya.

Benang dalam proses implementasi dan proses yang berbeda. Masing-masing memiliki thread terpisah berjalan masuk, urutan keluar dan prosedur pelaksanaan perintah. Tapi thread ini tidak mampu melakukan secara mandiri, itu harus ada sesuai dengan aplikasi, memberikan beberapa benang eksekusi dikendalikan oleh aplikasi.

Setiap thread memiliki set sendiri dari register CPU, yang disebut konteks benang, konteks benang mencerminkan menjalankan terakhir dari negara benang CPU mendaftar.

Instruksi pointer dan stack pointer register adalah dua register konteks thread yang paling penting, benang selalu akan berjalan dalam konteks proses, alamat ini digunakan untuk menandai proses yang memiliki benang dari ruang alamat memori.

  • Thread dapat mendahului (terganggu).
  • Di thread lain yang berjalan, benang dapat diselenggarakan di penundaan (juga dikenal sebagai tidur) - ini adalah benang konsesi.

Mulai belajar Python benang

benang Python digunakan dalam dua cara: dengan fungsi atau kelas untuk membungkus objek benang.

Fungsional: fungsi memanggil modul benang start_new_thread () untuk menghasilkan thread baru. Sintaksnya adalah sebagai berikut:

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

Parameter Deskripsi:

  • Fungsi - fungsi benang.
  • args - parameter benang dilewatkan ke fungsi, ia harus menjadi tipe tuple.
  • kwargs - Opsional.

contoh:

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

Hasil output program di atas adalah sebagai berikut:

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

Ujung benang yang umumnya mengandalkan akhir alami dari fungsi benang, juga dapat memanggil thread.exit fungsi benang (), dia melempar pengecualian SystemExit, mencapai tujuan keluar benang.


threading modul

Python menyediakan dukungan untuk threading melalui dua perpustakaan standar benang dan threading. benang menyediakan tingkat rendah, benang asli dan kunci sederhana.

Lainnya modul metode benang memberikan:

  • threading.currentThread (): Mengembalikan variabel thread saat ini.
  • threading.enumerate (): Mengembalikan daftar thread berjalan mengandung. Mengacu menjalankan benang dimulai sebelum akhirnya, itu tidak termasuk benang sebelum memulai dan setelah penghentian.
  • threading.activeCount (): Mengembalikan jumlah thread yang sedang berjalan, dan len (threading.enumerate ()) memiliki hasil yang sama.

Selain penggunaan metode, modul threading juga menyediakan kelas Thread untuk menangani benang, kelas Thread memberikan metode berikut:

  • menjalankan (): untuk menunjukkan metode benang aktif.
  • mulai (): memulai aktivitas benang.

  • bergabung ([waktu]): Tunggu sampai benang dibatalkan.Ini blok thread memanggil sampai metode thread ini bergabung () disebut suspensi - keluar normal atau membuang pengecualian tertangani - atau batas waktu opsional terjadi.
  • IsAlive (): Mengembalikan benang aktif.
  • getName (): Mengembalikan nama benang.
  • setName (): Mengatur nama benang.

Gunakan Threading Modul untuk membuat benang

Menggunakan modul Threading untuk membuat thread, langsung diwarisi dari threading.Thread, kemudian menimpa __init__ metode dan menjalankan metode:

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

Hasil eksekusi program di atas adalah sebagai berikut;

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

Thread Sinkronisasi

Jika beberapa benang dari modifikasi data umum, hasil yang tak terduga mungkin terjadi, dalam rangka untuk memastikan keakuratan data, kita harus melakukan sinkronisasi beberapa thread.

objek thread menggunakan Lock dan Rlock dapat mencapai sinkronisasi thread sederhana, dua benda ini metode memperoleh dan metode rilis, bagi mereka yang membutuhkan setiap memungkinkan hanya satu data operasional benang, dapat ditempatkan dalam operasi memperoleh dan melepaskan metode dari kamar. Sebagai berikut:

Multithreading keuntungan adalah bahwa hal itu secara bersamaan dapat menjalankan beberapa tugas (setidaknya terasa seperti ini). Tapi ketika benang perlu berbagi data, mungkin tidak ada masalah sinkronisasi data.

Pertimbangkan kasus: daftar semua elemen adalah nol, benang "set" dari belakang ke depan semua elemen menjadi satu, dan benang "cetak" dari depan ke belakang yang bertugas membaca daftar dan cetak.

Kemudian, benang dapat "diatur" mulai berubah ketika thread "print" untuk mencetak daftar, itu akan menjadi setengah output dari setengah 0, yang data tidak disinkronkan. Untuk menghindari situasi ini, kami memperkenalkan konsep kunci.

Kunci memiliki dua negara - terkunci dan terkunci. Setiap kali thread seperti "set" untuk mengakses data bersama, Anda harus terlebih dahulu mendapatkan kunci, jika Anda sudah memiliki thread yang lain, seperti "print" untuk mendapatkan terkunci, kemudian membiarkan benang "mengatur" jeda, yang memblokir sinkron; menunggu sampai thread " mencetak "akses selesai, setelah rilis kunci, biarkan thread" set "untuk melanjutkan.

Setelah proses ini, ketika Anda mencetak daftar semua keluaran 0 atau 1 output penuh, tidak lagi muncul setengah malu 0 1 setengah.

contoh:

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

antrian prioritas thread (Antrian)

modul Antrian Python menyediakan sinkronisasi, kelas antrian benang-aman, termasuk FIFO (first in first out) Antrian antrian, LIFO (bertahan, keluar pertama) LifoQueue antrian, dan PriorityQueue antrian prioritas. antrian ini diimplementasikan mengunci primitif dapat digunakan secara langsung di beberapa thread. Anda dapat menggunakan antrian untuk mencapai sinkronisasi antara benang.

Modul antrian metode yang umum digunakan:

  • Queue.qsize () mengembalikan ukuran antrian
  • Queue.empty () jika antrian kosong, kembali Benar, Salah dan sebaliknya
  • Queue.full () Jika antrian penuh, kembali Benar, False dan sebaliknya
  • Sesuai dengan ukuran dan maxsize Queue.full
  • Queue.get ([blok [, batas waktu]]) Mendapat antrian, waktu tunggu tunggu
  • Queue.get_nowait () bukan Queue.get (False)
  • Queue.put (item) menulis antrian, batas waktu menunggu waktu
  • Queue.put_nowait (item) cukup Queue.put (item, False)
  • Queue.task_done () setelah selesainya pekerjaan, Queue.task_done () fungsi mengirimkan sinyal untuk tugas telah selesai antrian
  • Queue.join () benar-benar berarti sampai antrian kosong, kemudian melakukan operasi lain

contoh:

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

Hasil dari program di atas:

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