Các loại luồng trong Python

Trong bài viết này, chúng tôi sẽ đề cập đến các tính năng chính của Python và SQL, những điểm tương đồng và khác biệt chính của chúng cũng như bạn nên chọn cái nào trước để bắt đầu hành trình khoa học dữ liệu của mình

Javier Canales Luna

12 phút

Dữ liệu văn bản trong Python Cheat Sheet

Chào mừng bạn đến với bảng gian lận của chúng tôi để làm việc với dữ liệu văn bản trong Python. Chúng tôi đã biên soạn một danh sách các hàm và gói hữu ích nhất để dọn dẹp, xử lý và phân tích dữ liệu văn bản trong Python, cùng với các ví dụ và giải thích rõ ràng, vì vậy bạn sẽ có mọi thứ cần biết về cách làm việc với dữ liệu văn bản trong Python.

Hướng dẫn về tập hợp và lý thuyết tập hợp trong Python

Tìm hiểu về bộ Python. chúng là gì, cách tạo chúng, khi nào sử dụng chúng, các chức năng tích hợp và mối quan hệ của chúng với các hoạt động lý thuyết thiết lập

Hướng dẫn về gấu trúc. Khung dữ liệu trong Python

Khám phá phân tích dữ liệu với Python. Pandas DataFrames giúp thao tác dữ liệu của bạn dễ dàng, từ việc chọn hoặc thay thế các cột và chỉ mục để định hình lại dữ liệu của bạn

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 nhánh của tập lệnh hoặc chương trình máy tính trong hai hoặc nhiều tác vụ song song [được triển khai trên một bộ xử lý bằng đa nhiệm]. Chủ đề thường được chứa trong các quy trình. Nhiều luồng có thể tồn tại trong cùng một quy trình. Các luồng này chia sẻ bộ nhớ và trạng thái của tiến 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

  • Chủ đề hạt nhân
  • Chủ đề không gian người dùng hoặc chủ đề người dùng

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

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

Mỗi quá trình có ít nhất một luồng, tôi. e. bản thân quá trình. Một tiến trình có thể bắt đầu nhiều luồng. Hệ điều hành thực thi các luồng này giống như các "quy trình" song song. Trên một máy có bộ xử lý đơn, tính song song này đạt được bằng cách lập lịch luồng hoặc chia 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 có nhiều CPU, bởi vì các luồng này có thể được thực thi đồng thời thực sự
  • 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 một và trên nhiều CPU
  • Các luồng của một tiến trình có thể chia sẻ bộ nhớ của các biến toàn cục. Nếu một biến toàn cục được thay đổi trong một luồng, thay đổi này có hiệu lực đối với tất cả các luồng. Một luồng 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 đôi khi chúng được gọi là quy trình trọng lượng nhẹ [LWP]

Đào tạo Python trực tiếp

Thưởng thức trang này?

Thấy. Tổng quan về các khóa học Python trực tiếp

đăng ký tại đây

Chủ đề trong Python

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

  • chủ đề
  • xâu chuỗi

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. Người dùng đã được khuyến khích sử dụng mô-đun luồng thay thế. Vì vậy, trong Python 3, "luồng" mô-đun không còn khả dụng nữa. Nhưng điều đó không thực sự đúng. Nó đã được đổi tên thành "_thread" vì sự không tương thích ngược trong Python3

Mô-đun "luồng" xử lý một luồng như một chức năng, trong khi "luồng" mô-đun được triển khai theo cách hướng đối tượng, tôi. e. mỗi chủ đề 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 biệt với mô-đun Chủ đề. Để làm được điều này, chúng ta có thể sử dụng hàm thread. 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ề mã định danh của nó. Chuỗi thực thi chức năng "hàm" [hàm là một tham chiếu đến một hàm] với danh sách đối số args [phải là một danh sách hoặc một bộ]. Đối số kwargs tùy chọn chỉ định một từ điển các đối số từ khóa. Khi chức năng trở lại, luồng âm thầm thoát. Khi chức năng kết thúc với một ngoại lệ chưa được xử lý, dấu vết ngăn xếp được in và sau đó luồng thoát [nhưng các luồng khác vẫn 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."]

Hàm raw_input[] trong ví dụ trước là cần thiết, vì nếu không thì tất cả các luồng sẽ bị thoát nếu chương trình chính kết thúc. raw_input[] đợi cho đến khi nội dung nào đó được nhập vào

Chúng tôi mở rộng ví dụ trước với bộ đếm cho 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 mà chúng ta có thể mong đợi nó hoạt động. Chuyện gì thế?

Vấn đề là vòng lặp while cuối cùng sẽ đạt được ngay cả trước khi một trong các luồng có thể tăng 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

Các câu lệnh 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 1
  • giá trị mới phải được gán cho num_threads

Các lỗi như thế này xảy ra trong trường hợp gán gia tăng

Chuỗi đầu tiên đọc biến num_threads, biến này vẫn có giá trị 0. Sau khi đọc giá trị này, luồng sẽ được hệ điều hành đưa vào chế độ ngủ. Bây giờ đến lượt chủ đề 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 chế độ ngủ quá sớm, i. e. 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 chế độ ngủ. Bây giờ đến lượt luồng thứ ba, một lần nữa đọc là 0, nhưng bộ đếm lúc này đáng lẽ phải là 2. Mỗi luồng này giờ đây gán giá trị 1 cho bộ đếm. Các vấn đề tương tự xảy ra với toán tử giảm dần

Giải pháp

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 bằng các đối tượng khóa. Những phần này sẽ được xử lý nguyên tử, tôi. e. trong khi thực hiện một phần như vậy, một luồng sẽ không bị gián đoạn hoặc đưa vào chế độ ngủ

Chủ đề phương pháp. Alex_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

Phần đầu của phần quan trọng được đánh dấu bằng

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 bằng
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 ổ khóa trông như thế này

________số 8_______

Đào tạo Python trực tiếp

Thưởng thức trang này?

Thấy. Tổng quan về các khóa học Python trực tiếp

đăng ký tại đây

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 được gì 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 pháp hoạt động của luồng. lớp chủ đề. Phân luồng lớp. Chủ đề có một phương thức bắt đầu [], có thể bắt đầu một Chủ đề. Nó kích hoạt phương thức run[], phương thức này phải được quá tải. Phương thức tham gia [] đảm bảo rằng chương trình chính đợi cho đến khi tất cả các luồng kết thúc

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 xem một số có phải 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ủ đề

Các ví dụ trước của chương này hoàn toàn mang tính giáo khoa 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ạng cục bộ địa chỉ nào đ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, vì nó có thể gây nhiễu mạng nếu có quá nhiều ping được bắt đầu cùng một lúc. Theo cách thủ công, chúng tôi sẽ thực hiện các thao tác sau đối với 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 đến 192. 168. 178. lần lượt là 255. Mỗi lần chúng ta phải đợi vài giây để nhận giá trị trả về. Điều này có thể được lập trình bằng Python với vòng lặp for trên dải địa chỉ của địa chỉ IP và hệ điều hành. popen["ping -q -c2 "+ip,"r"]

Một giải pháp không có luồng sẽ rất kém hiệu quả, vì tập lệnh sẽ phải đợi mỗi lần ping

Có bao nhiêu luồng trong Python?

Nói chung, Python chỉ sử dụng một luồng để thực thi tập hợp các câu lệnh đã viết. Điều này có nghĩa là trong python, chỉ có một luồng sẽ được thực thi tại một thời điểm.

Lớp chủ đề Python là gì?

Python đa luồng . Lớp Chủ đề đại diện cho một hoạt động chạy trong một luồng điều khiển riêng biệt .

Ví dụ về phân luồng trong Python là gì?

Các luồng Python được được sử dụng trong trường hợp việc thực thi một tác vụ liên quan đến việc chờ đợi . Một ví dụ sẽ là tương tác với một dịch vụ được lưu trữ trên một máy tính khác, chẳng hạn như máy chủ web. Luồng cho phép python thực thi mã khác trong khi chờ đợi; .

Chuỗi chính Python là gì?

Trong điều kiện bình thường, luồng chính là luồng mà trình thông dịch Python được bắt đầu . Mới trong phiên bản 3. 4. Đặt chức năng theo dõi cho tất cả các luồng bắt đầu từ mô-đun luồng. func sẽ được chuyển đến sys. settrace[] cho mỗi luồng, trước khi phương thức run[] của nó được gọi.

Chủ Đề