Hướng dẫn which module supports the usages of threading in python? - mô-đun nào hỗ trợ cách sử dụng luồng trong python?

Bởi Bernd Klein. Sửa đổi lần cuối: 01 tháng 2 năm 2022.Bernd Klein. Last modified: 01 Feb 2022.

Trên trang này

Định nghĩa của một chủ đề

Một luồng hoặc một luồng thực thi được định nghĩa trong khoa học máy tính là đơn vị nhỏ nhất có thể được lên lịch trong một hệ điều hành. Các luồng thường được tạo bởi một ngã ba của tập lệnh máy tính hoặc chương trình song song hai hoặc nhiều (được thực hiện trên một bộ xử lý duy nhất bằng nhiều nhiệm vụ). Chủ đề thường được chứa trong các quy trình. Nhiều hơn một luồng có thể tồn tại trong cùng một quá trình. Các chủ đề này chia sẻ bộ nhớ và trạng thái của quá trình. Nói cách khác: họ chia sẻ mã hoặc hướng dẫn và giá trị của các biến của nó.

Có hai loại chủ đề khác nhau:

  • Kernel Chủ đề
  • Chủ đề không gian người dùng hoặc luồng người dùng

Chủ đề kernel là một phần của hệ điều hành, trong khi các luồng không gian người dùng không được triển khai trong kernel.

Theo một cách nhất định, các luồng không gian người dùng có thể được coi là một phần mở rộng của khái niệm chức năng của ngôn ngữ lập trình. Vì vậy, một luồng không gian người dùng chủ đề tương tự như một cuộc gọi chức năng hoặc thủ tục. Nhưng có sự khác biệt đối với các chức năng thường xuyên, đặc biệt là hành vi trả lại.

Hướng dẫn which module supports the usages of threading in python? - mô-đun nào hỗ trợ cách sử dụng luồng trong python?

Mỗi quá trình có ít nhất một luồng, tức là chính quá trình. Một quá trình có thể bắt đầu nhiều luồng. Hệ điều hành thực hiện các luồng này như "quy trình" song song. Trên một máy xử lý duy nhất, sự song song này đạt được bằng cách lập lịch trình hoặc thời gian.

Ưu điểm của luồng:

  • Các chương trình đa luồng có thể chạy nhanh hơn trên các hệ thống máy tính với nhiều CPU, bởi vì các chủ đề luận án có thể được thực thi thực sự đồng thời.
  • Một chương trình có thể vẫn đáp ứng với đầu vào. Điều này đúng cả trên đơn và trên nhiều CPU
  • Chủ đề của một quá trình có thể chia sẻ bộ nhớ của các biến toàn cầu. Nếu một biến toàn cầu được thay đổi trong một luồng, thay đổi này là hợp lệ cho tất cả các luồng. Một chủ đề có thể có các biến cục bộ.

Việc xử lý các luồng đơn giản hơn việc xử lý các quy trình cho một hệ điều hành. Đó là lý do tại sao chúng đôi khi được gọi là quy trình trọng lượng ánh sáng (LWP)

Chủ đề trong Python

Hướng dẫn which module supports the usages of threading in python? - mô-đun nào hỗ trợ cách sử dụng luồng trong python?

Có hai mô -đun hỗ trợ việc sử dụng các luồng trong Python:

  • Chủ đề và
    and
  • luồng

Xin lưu ý: Mô -đun luồng đã được coi là "không dùng nữa" trong một thời gian khá dài. Thay vào đó, người dùng đã được khuyến khích sử dụng mô -đun luồng. Vì vậy, trong Python 3, mô -đun "luồng" không còn nữa. Nhưng điều đó không thực sự đúng: nó đã được đổi tên thành "_thread" cho sự không tương thích ngược trong Python3.

Mô -đun "luồng" coi một luồng là một hàm, trong khi mô -đun "luồng" được triển khai theo cách định hướng đối tượng, tức là mỗi luồng tương ứng với một đối tượng.

Mô -đun chủ đề

Có thể thực thi các chức năng trong một luồng riêng với luồng mô -đun. Để làm điều này, chúng ta có thể sử dụng luồng chức năng.START_NEW_THREAD:

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
1

Phương thức này bắt đầu một luồng mới và trả về định danh của nó. Chủ đề thực thi hàm "hàm" (hàm là tham chiếu đến hàm) với danh sách đối số ARGS (phải là danh sách hoặc một tuple). Đối số kwargs tùy chọn chỉ định một từ điển của các đối số từ khóa. Khi hàm trở lại, luồng âm thầm thoát ra. Khi chức năng chấm dứt với một ngoại lệ chưa được xử lý, một dấu vết ngăn xếp được in và sau đó các luồng thoát ra (nhưng các luồng khác tiếp tục chạy).

Ví dụ cho một chủ đề trong Python:

from thread import start_new_thread

def heron(a):
    """Calculates the square root of a"""
    eps = 0.0000001
    old = 1
    new = 1
    while True:
        old,new = new, (new + a/new) / 2.0
        print old, new
        if abs(new - old) < eps:
            break
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))

c = raw_input("Type something to quit.")

Raw_Input () trong ví dụ trước là cần thiết, bởi vì nếu không thì tất cả các luồng sẽ được thoát, nếu chương trình chính kết thúc. Raw_Input () Đợi cho đến khi một cái gì đó đã được gõ vào.

Chúng tôi mở rộng ví dụ trước với các bộ đếm cho các chủ đề.

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass

Kịch bản trên không hoạt động theo cách chúng ta có thể mong đợi nó hoạt động. Chuyện gì thế?

Vấn đề là vòng cuối cùng trong khi sẽ đạt được ngay cả trước khi một trong các luồng có thể tăng số bộ đếm num_threads.

Nhưng có một vấn đề nghiêm trọng khác:

Vấn đề phát sinh bởi các bài tập cho num_thread

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
2

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
3

Những tuyên bố gán này không phải là nguyên tử. Một nhiệm vụ như vậy bao gồm ba hành động:

  • Đọc giá trị của num_thread
  • Một phiên bản INT mới sẽ được tăng hoặc giảm bởi 1
  • Giá trị mới phải được gán cho num_threads

Lỗi như thế này xảy ra trong trường hợp bài tập tăng:

Chủ đề đầu tiên đọc biến NUM_THREADS, vẫn có giá trị 0. Sau khi đọc giá trị này, chủ đề được hệ điều hành đưa vào giấc ngủ. Bây giờ là lượt của luồng thứ hai: nó cũng đọc giá trị của biến num_threads, vẫn là 0, bởi vì luồng đầu tiên đã được đưa vào ngủ quá sớm, tức là trước khi nó có thể tăng giá trị của nó lên 1. Bây giờ Chủ đề thứ hai được đưa vào giấc ngủ. Bây giờ đến lượt chủ đề thứ ba, một lần nữa đọc 0, nhưng bộ đếm đáng lẽ phải là 2. Mỗi chủ đề này gán cho giá trị 1 cho bộ đếm. Các vấn đề tương tự xảy ra với hoạt động giảm.

Dung dịch

Các vấn đề thuộc loại này có thể được giải quyết bằng cách xác định các phần quan trọng với các đối tượng khóa. Các phần này sẽ được xử lý nguyên tử, tức là trong quá trình thực hiện phần như vậy, một luồng sẽ không bị gián đoạn hoặc đưa vào giấc ngủ.

Phương thức Thread.ALLOCATE_LOCK được sử dụng để tạo một đối tượng khóa mới:

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
4

Sự khởi đầu của một phần quan trọng được gắn thẻ

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
5 và kết thúc với
from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
6.

Giải pháp với các khóa trông như thế này:

from thread import start_new_thread, allocate_lock
num_threads = 0
thread_started = False
lock = allocate_lock()
def heron(a):
    global num_threads, thread_started
    lock.acquire()
    num_threads += 1
    thread_started = True
    lock.release()
    
    ...

    lock.acquire()
    num_threads -= 1
    lock.release()
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))

while not thread_started:
    pass
while num_threads > 0:
    pass

Mô -đun luồng

Chúng tôi muốn giới thiệu mô -đun luồng với một ví dụ. Chủ đề của ví dụ không làm nhiều, về cơ bản nó chỉ ngủ trong 5 giây và sau đó in ra một tin nhắn:

import time
from threading import Thread

def sleeper(i):
    print "thread %d sleeps for 5 seconds" % i
    time.sleep(5)
    print "thread %d woke up" % i

for i in range(10):
    t = Thread(target=sleeper, args=(i,))
    t.start()

Phương thức Hoạt động của lớp. Lớp học: Lớp luồng.Thread có một phương thức start (), có thể bắt đầu một luồng. Nó kích hoạt phương thức chạy (), phải bị quá tải. Phương thức tham gia () đảm bảo rằng chương trình chính chờ cho đến khi tất cả các luồng đã chấm dứt.

Tập lệnh trước đó trả về đầu ra sau:

thread 0 sleeps for 5 seconds
thread 1 sleeps for 5 seconds
thread 2 sleeps for 5 seconds
thread 3 sleeps for 5 seconds
thread 4 sleeps for 5 seconds
thread 5 sleeps for 5 seconds
thread 6 sleeps for 5 seconds
thread 7 sleeps for 5 seconds
thread 8 sleeps for 5 seconds
thread 9 sleeps for 5 seconds
thread 1 woke up
thread 0 woke up
thread 3 woke up
thread 2 woke up
thread 5 woke up
thread 9 woke up
thread 8 woke up
thread 7 woke up
thread 6 woke up
thread 4 woke up

Ví dụ tiếp theo hiển thị một luồng, xác định, nếu một số là số nguyên tố hay không. Chủ đề được xác định với mô -đun luồng:

import threading 
 
class PrimeNumber(threading.Thread): 
  def __init__(self, number): 
    threading.Thread.__init__(self) 
    self.Number = number
 
  def run(self): 
    counter = 2 
    while counter*counter < self.Number: 
      if self.Number % counter == 0: 
        print "%d is no prime number, because %d = %d * %d" % ( self.Number, self.Number, counter, self.Number / counter) 
                return 
            counter += 1 
        print "%d is a prime number" % self.Number
threads = [] 
while True: 
    input = long(raw_input("number: ")) 
    if input < 1: 
        break 
 
    thread = PrimeNumber(input) 
    threads += [thread] 
    thread.start() 
 
for x in threads: 
    x.join()

Với khóa, nó sẽ trông như thế này:

class PrimeNumber(threading.Thread):
    prime_numbers = {} 
    lock = threading.Lock()
    
    def __init__(self, number): 
        threading.Thread.__init__(self) 
        self.Number = number
        PrimeNumber.lock.acquire() 
        PrimeNumber.prime_numbers[number] = "None" 
        PrimeNumber.lock.release() 
 
    def run(self): 
        counter = 2
        res = True
        while counter*counter < self.Number and res: 
            if self.Number % counter == 0: 
               res = False 
            counter += 1 
        PrimeNumber.lock.acquire() 
        PrimeNumber.prime_numbers[self.Number] = res 
        PrimeNumber.lock.release() 
threads = [] 
while True: 
    input = long(raw_input("number: ")) 
    if input < 1: 
        break 
 
    thread = PrimeNumber(input) 
    threads += [thread] 
    thread.start() 
 
for x in threads: 
    x.join()

Ping với chủ đề

Hướng dẫn which module supports the usages of threading in python? - mô-đun nào hỗ trợ cách sử dụng luồng trong python?

Các ví dụ trước đây của chương này hoàn toàn được quan tâm, và không có khả năng áp dụng thực tế. Ví dụ sau đây cho thấy một ứng dụng thú vị, có thể dễ dàng sử dụng. Nếu bạn muốn xác định trong một mạng cục bộ địa chỉ đang hoạt động hoặc máy tính nào đang hoạt động, tập lệnh này có thể được sử dụng. Nhưng bạn phải cẩn thận với phạm vi, bởi vì nó có thể gây nhiễu mạng, nếu quá nhiều ping được bắt đầu cùng một lúc. Theo cách chính xác, chúng tôi sẽ làm như sau cho một mạng 192.168.178.x: Chúng tôi sẽ ping địa chỉ 192.168.178.0, 192.168.178.1, 192.168.178.3 cho đến 192.168.178.255 lần lượt. Mỗi lần chúng tôi sẽ phải đợi một vài giây cho các giá trị trả về. Điều này có thể được lập trình bằng Python với một vòng lặp trên phạm vi địa chỉ của địa chỉ IP và OS.Popen ("ping -q -c2"+ip, "r").

Một giải pháp không có chủ đề là không hiệu quả cao, bởi vì tập lệnh sẽ phải chờ mọi ping.

Giải pháp với chủ đề:

import os, re

received_packages = re.compile(r"(\d) received")
status = ("no response","alive but losses","alive")

for suffix in range(20,30):
   ip = "192.168.178."+str(suffix)
   ping_out = os.popen("ping -q -c2 "+ip,"r")
   print "... pinging ",ip
   while True:
      line = ping_out.readline()
      if not line: break
      n_received = received_packages.findall(line)
      if n_received:
         print ip + ": " + status[int(n_received[0])]

Để hiểu tập lệnh này, chúng ta phải xem kết quả của một ping trên dòng lệnh shell:

$ ping -q -c2 192.168.178.26
PING 192.168.178.26 (192.168.178.26) 56(84) bytes of data.

--- 192.168.178.26 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.022/0.032/0.042/0.010 ms

Nếu một ping không dẫn đến thành công, chúng ta sẽ nhận được đầu ra sau:

$ ping -q -c2 192.168.178.23
PING 192.168.178.23 (192.168.178.23) 56(84) bytes of data.

--- 192.168.178.23 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1006ms

Đây là giải pháp nhanh với các chủ đề:

from thread import start_new_thread

num_threads = 0
def heron(a):
    global num_threads
    num_threads += 1
    
    # code has been left out, see above
    num_threads -= 1
    return new

start_new_thread(heron,(99,))
start_new_thread(heron,(999,))
start_new_thread(heron,(1733,))
start_new_thread(heron,(17334,))

while num_threads > 0:
    pass
0

Mô -đun nào được sử dụng để đa luồng trong Python?

Mô -đun luồng. Mô-đun luồng là một triển khai đa luồng cấp cao được sử dụng để triển khai một ứng dụng trong Python. Để sử dụng đa luồng, chúng ta cần nhập mô -đun luồng trong chương trình Python.. The threading module is a high-level implementation of multithreading used to deploy an application in Python. To use multithreading, we need to import the threading module in Python Program.

Chủ đề được sử dụng cho trong Python là gì?

Việc luồng trong Python được sử dụng để chạy nhiều luồng (tác vụ, cuộc gọi chức năng) cùng một lúc.Lưu ý rằng điều này không có nghĩa là chúng được thực thi trên các CPU khác nhau.Các chủ đề Python sẽ không làm cho chương trình của bạn nhanh hơn nếu nó đã sử dụng thời gian CPU 100 %.to run multiple threads (tasks, function calls) at the same time. Note that this does not mean that they are executed on different CPUs. Python threads will NOT make your program faster if it already uses 100 % CPU time.

Tên của pythons được tích hợp trong mô -đun cho chủ đề là gì?

Mô -đun luồng trong Python cung cấp các cuộc gọi chức năng được sử dụng để tạo các luồng mới.Hàm __init__ được sử dụng để khởi tạo dữ liệu được liên kết với các luồng mới trong khi, hàm chạy xác định hành vi của luồng ngay khi luồng bắt đầu thực thi.threading module in python provides function calls that is used to create new threads. The __init__ function is used for initializing the data associated with the new threads whereas, the run function defines the thread's behavior as soon as the thread starts it's execution.

Chủ đề mô -đun là gì?

Chủ đề mô -đun cải thiện thông lượng và hiệu quả công suất của mô -đun bộ nhớ bằng cách áp dụng song song với các truy cập dữ liệu mô -đun.Đổi mới này phân chia mô -đun thành hai kênh bộ nhớ riêng lẻ và xen kẽ các lệnh đến từng kênh tương ứng.improves the throughput and power efficiency of a memory module by applying parallelism to module data accesses. This innovation partitions the module into two individual memory channels and interleaves the commands to each respective channel.