Biến toàn cục Python trong gọi lại

Chọn một trang web để nhận nội dung đã dịch nếu có và xem các sự kiện và ưu đãi tại địa phương. Dựa trên vị trí của bạn, chúng tôi khuyên bạn nên chọn.

Bạn cũng có thể chọn một trang web từ danh sách sau

Làm thế nào để có được hiệu suất trang web tốt nhất

Chọn trang Trung Quốc (bằng tiếng Trung hoặc tiếng Anh) để có hiệu suất trang tốt nhất. Các trang web quốc gia khác của MathWorks không được tối ưu hóa cho các lượt truy cập từ vị trí của bạn

Nhưng không có tùy chọn nào trong số này có sẵn cho tôi. Tôi đã thấy một số bài đăng ở đây trên diễn đàn đề xuất rằng mọi người sử dụng các biến toàn cục (điều này sẽ làm rối tung bất kỳ cấu trúc nút lớn hơn nào) hoặc các lớp, nhưng việc sử dụng các lớp vẫn chỉ cấp quyền truy cập vào dữ liệu trong lớp. Để minh họa quan điểm của tôi, tôi sẽ đăng một tập lệnh (không cần chạy tập lệnh này)

#!/usr/bin/env python
import rospy
from std_msgs.msg import Int64
from std_srvs.srv import SetBool
from geometry_msgs.msg import Twist

class NumberCounter:
    def __init__(self):
        self.counter = 0
        self.number_subscriber = rospy.Subscriber("/cmd_vel", Twist, self.callback_number)
        self.reset_service = rospy.Service("/reset_counter", SetBool, self.callback_reset_counter)
    def callback_number(self, msg):
        self.counter += msg.linear.x
        self.asd = 'IAmUsedInTheOtherCallback'
        new_msg = Int64()
        new_msg.data = self.counter

    def callback_reset_counter(self, req):
        print(self.asd)
        if req.data:
            self.counter = 0
            return True, "Counter has been successfully reset"
        return False, "Counter has not been reset"

if __name__ == '__main__':
    rospy.init_node('number_counter')
    NumberCounter()
    # Now I want to use the data used in the callback_number function but there is no way for me to call it 
    #either as an attribute (because I cannot return outside the function) or
    #as a method (because I do not have the input 'msg')
    #NumberCounter.data <----- How do I get this so I can use it in other statements?
    rospy.spin()

Nhìn vào bình luận ngay phía trên. spin() Tôi muốn có thể lấy dữ liệu thô được sử dụng trong hàm gọi lại hoặc giá trị trả về của hàm gọi lại đó nhưng dường như không có cách nào để thực hiện?

Giải pháp cuối cùng chúng tôi đưa ra là xuất bản trong mỗi cuộc gọi lại và sau đó có những người đăng ký mới đăng ký chủ đề đó, đây là cách duy nhất chúng tôi có thể giải quyết vấn đề này. Tuy nhiên, có vẻ ngu ngốc khi phải tạo một nhà xuất bản và người đăng ký hoàn toàn mới chỉ để sử dụng dữ liệu hoặc câu lệnh trả về của hàm gọi lại

lý do tại sao nó hoạt động trong Trình chỉnh sửa nguồn chứ không phải trong parm là các biến được tự động mở rộng trong parms trước khi văn bản được chuyển đến python (hoặc VEX)
bạn có thể thấy điều đó bằng MMB trên nhãn parm
vì vậy đó là lý do tại sao bạn cần thoát, đó là để ngăn houdini đánh giá biến, không liên quan gì đến Python trong trường hợp này

Tomas Slancik
Người giám sát ngoại hối
Phương pháp Studios, NY

Bạn có thể chỉ định chức năng gọi lại tùy chỉnh khi sử dụng các hàm apply_async(), map_async() và starmap_async() trong lớp ThreadPool thông qua đối số "gọi lại"

Trong hướng dẫn này, bạn sẽ khám phá cách sử dụng các hàm gọi lại với ThreadPool trong Python

Bắt đầu nào

Mục lục

Cần sử dụng Gọi lại với ThreadPool

Cung cấp một nhóm các luồng có thể tái sử dụng để thực hiện các tác vụ đặc biệt

Một đối tượng nhóm luồng kiểm soát nhóm luồng công nhân mà công việc có thể được gửi tới

— đa xử lý — Song song dựa trên quy trình

Lớp ThreadPool mở rộng lớp Pool. Lớp Pool cung cấp một nhóm các quy trình công nhân cho đồng thời dựa trên quy trình

Mặc dù lớp ThreadPool nằm trong mô-đun đa xử lý nhưng lớp này cung cấp tính đồng thời dựa trên luồng và phù hợp nhất với các tác vụ liên kết với IO, chẳng hạn như đọc hoặc ghi từ ổ cắm hoặc tệp

Một ThreadPool có thể được cấu hình khi nó được tạo, nó sẽ chuẩn bị các luồng mới

Chúng ta có thể đưa ra các tác vụ một lần cho ThreadPool bằng các phương thức như apply() hoặc chúng ta có thể áp dụng chức năng tương tự cho một mục có thể lặp lại bằng các phương thức như map()

Sau đó, kết quả cho các tác vụ đã phát hành có thể được truy xuất đồng bộ hoặc chúng tôi có thể truy xuất kết quả của các tác vụ sau này bằng cách sử dụng các phiên bản không đồng bộ của các phương thức, chẳng hạn như apply_async() và map_async()

Khi phát hành các tác vụ cho ThreadPool không đồng bộ, chúng tôi có thể cần định cấu hình chức năng gọi lại. Đó là, chúng ta có thể cần có một chức năng tùy chỉnh được gọi tự động với kết quả của từng tác vụ

Làm cách nào chúng ta có thể sử dụng các hàm gọi lại với ThreadPool trong Python?

Chạy các vòng lặp của bạn bằng cách sử dụng tất cả các CPU, tải xuống cuốn sách MIỄN PHÍ của tôi để tìm hiểu cách thực hiện

Cách cấu hình chức năng gọi lại

ThreadPool hỗ trợ chức năng gọi lại tùy chỉnh

Các chức năng gọi lại được gọi trong hai tình huống

  • Với kết quả của một nhiệm vụ
  • Khi một lỗi được đưa ra trong một nhiệm vụ

Chúng tôi chỉ xem xét các cuộc gọi lại được gọi với kết quả của một tác vụ, được gọi là cuộc gọi lại kết quả

Các cuộc gọi lại kết quả được hỗ trợ trong ThreadPool khi thực hiện các tác vụ không đồng bộ với bất kỳ chức năng nào sau đây

  • áp dụng_async(). Để phát hành một tác vụ không đồng bộ
  • map_async(). Để phát hành nhiều tác vụ với một đối số không đồng bộ
  • starmap_async(). Để phát hành nhiều tác vụ với nhiều đối số không đồng bộ

Một cuộc gọi lại kết quả có thể được chỉ định thông qua đối số "gọi lại"

Đối số chỉ định tên của hàm tùy chỉnh để gọi với kết quả của tác vụ hoặc tác vụ không đồng bộ

Lưu ý, chức năng gọi lại được định cấu hình sẽ được gọi, ngay cả khi chức năng tác vụ của bạn không có giá trị trả về. Trong trường hợp đó, giá trị trả về mặc định là Không có sẽ được chuyển thành đối số cho hàm gọi lại

Hàm có thể có bất kỳ tên nào bạn thích, miễn là nó không xung đột với tên hàm đã được sử dụng

Nếu gọi lại được chỉ định thì nó phải là một cuộc gọi có thể chấp nhận một đối số. Khi kết quả trở nên sẵn sàng gọi lại được áp dụng cho nó

— đa xử lý — Song song dựa trên quy trình

Ví dụ: nếu apply_async() được định cấu hình với hàm gọi lại, thì hàm gọi lại sẽ được gọi với giá trị trả về của hàm tác vụ đã được thực thi

1

2

3

4

5

6

7

# chức năng gọi lại kết quả

def result_callback(kết quả):

in(kết quả)

 

.. .

# phát hành một nhiệm vụ duy nhất

kết quả = apply_async(. . . , gọi lại=result_callback)

Ngoài ra, nếu map_async() hoặc starmap_async() được định cấu hình bằng hàm gọi lại, thì hàm gọi lại sẽ được gọi với một giá trị trả về có thể lặp lại từ tất cả các tác vụ được cấp cho ThreadPool

1

2

3

4

5

6

7

8

9

# chức năng gọi lại kết quả

def result_callback(kết quả):

# lặp lại tất cả các kết quả

cho giá trị trong kết quả.

in(giá trị)

 

.. .

# phát hành một nhiệm vụ duy nhất

kết quả = map_async(. . . , gọi lại=result_callback)

Các cuộc gọi lại kết quả nên được sử dụng để thực hiện một hành động nhanh chóng với kết quả hoặc kết quả của các tác vụ đã phát hành từ ThreadPool

Chúng không nên chặn hoặc thực thi trong thời gian dài vì chúng sẽ chiếm tài nguyên của ThreadPool trong khi chạy

Các cuộc gọi lại phải hoàn thành ngay lập tức vì nếu không thì chuỗi xử lý kết quả sẽ bị chặn

— đa xử lý — Song song dựa trên quy trình

Bây giờ chúng ta đã biết cách định cấu hình chức năng gọi lại kết quả, hãy xem một số ví dụ đã hoạt động

Bị bối rối bởi API lớp ThreadPool?
Tải xuống bảng cheat PDF MIỄN PHÍ của tôi

Hàm gọi lại ví dụ cho apply_async()

Chúng ta có thể khám phá cách sử dụng gọi lại kết quả với ThreadPool khi thực hiện các tác vụ thông qua hàm apply_async()

Trong ví dụ này, chúng tôi sẽ xác định một tác vụ tạo một số ngẫu nhiên, báo cáo số đó, chặn một lúc, sau đó trả về giá trị đã được tạo. Hàm gọi lại sẽ được xác định nhận giá trị trả về từ hàm tác vụ và báo cáo giá trị

Đầu tiên, chúng ta có thể định nghĩa hàm gọi lại kết quả

Hàm nhận một giá trị trả về duy nhất từ ​​hàm tác vụ đích và báo cáo trực tiếp

Hàm result_callback() bên dưới thực hiện điều này

1

2

3

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Callback got. {result}')

Tiếp theo, chúng ta có thể xác định chức năng nhiệm vụ mục tiêu

Hàm lấy một mã định danh số nguyên duy nhất cho tác vụ. Sau đó, nó tạo ra một số ngẫu nhiên trong khoảng từ 0 đến 1 và ngủ trong một phần giây để mô phỏng nỗ lực tính toán. Cuối cùng, nó trả về giá trị ngẫu nhiên đã được tạo

Hàm task() bên dưới thực hiện điều này

1

2

3

4

5

6

7

8

9

10

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    # tạo giá trị

    giá trị = ngẫu nhiên()

    # báo cáo thư

    print(f'Task {identifier} đang thực thi)

   # khối trong giây lát

    ngủ(giá trị)

    # trả về giá trị đã tạo

    trả về giá trị

Sau đó, chúng tôi xác định một ThreadPool với số lượng chuỗi worker mặc định. Trong trường hợp này, chúng tôi sử dụng giao diện trình quản lý ngữ cảnh để đảm bảo ThreadPool tự động đóng lại sau khi chúng tôi hoàn thành với nó

1

2

3

4

.. .

# tạo và cấu hình thread pool

với Nhóm luồng() như pool:

    #.

Bạn có thể tìm hiểu thêm về giao diện trình quản lý bối cảnh trong hướng dẫn

  • Cách sử dụng Trình quản lý ngữ cảnh ThreadPool

Sau đó, chúng tôi sẽ đưa tác vụ tới ThreadPool bằng cách sử dụng apply_async() và chỉ định chức năng gọi lại kết quả để thực thi với kết quả của tác vụ

1

2

3

.. .

# phát hành nhiệm vụ cho nhóm luồng

kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

  • Cách sử dụng ThreadPool apply_async() trong Python

Cuối cùng, luồng chính sẽ đóng ThreadPool và đợi tác vụ được phát hành hoàn thành

1

2

3

4

5

.. .

# đóng nhóm chủ đề

nhóm. đóng()

# đợi tất cả các nhiệm vụ hoàn thành

nhóm. tham gia()

Bạn có thể tìm hiểu thêm về cách tham gia ThreadPool trong hướng dẫn

  • Cách tham gia một ThreadPool trong Python

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#Trăn Siêu Nhanh. com

# ví dụ về chức năng gọi lại cho apply_async()

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Callback got. {result}')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    # tạo giá trị

    giá trị = ngẫu nhiên()

    # báo cáo thư

    print(f'Task {identifier} đang thực thi)

   # khối trong giây lát

    ngủ(giá trị)

    # trả về giá trị đã tạo

    trả về giá trị

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Chạy ví dụ trước tiên khởi động ThreadPool với cấu hình mặc định

Sau đó, tác vụ được cấp cho ThreadPool. Sau đó, luồng chính sẽ đóng nhóm và đợi tác vụ đã phát hành hoàn thành

Chức năng nhiệm vụ thực thi, tạo một số ngẫu nhiên, báo cáo một tin nhắn, chặn và trả về một giá trị

Hàm gọi lại kết quả sau đó được gọi với giá trị được tạo, sau đó được báo cáo

Nhiệm vụ kết thúc và luồng chính thức dậy và tiếp tục, đóng chương trình

1

2

Nhiệm vụ 0 thực thi với 0. 17305995302320798

gọi lại đã nhận. 0. 17305995302320798

Tiếp theo, hãy xem một ví dụ về cách sử dụng hàm gọi lại với hàm map_async()


Khóa học Python ThreadPool miễn phí

Tải xuống bảng cheat API ThreadPool của tôi và như một phần thưởng, bạn sẽ nhận được quyền truy cập MIỄN PHÍ vào khóa học email 7 ngày của tôi

Khám phá cách sử dụng ThreadPool bao gồm cách định cấu hình số luồng công nhân và cách thực thi các tác vụ không đồng bộ

Tìm hiểu thêm
 


Hàm gọi lại ví dụ cho map_async()

Chúng ta có thể khám phá cách sử dụng gọi lại kết quả với ThreadPool khi thực hiện các tác vụ thông qua hàm map_async()

Trong ví dụ này, chúng ta có thể cập nhật ví dụ trước để thực hiện nhiều lệnh gọi hàm task(). Hàm gọi lại sau đó sẽ được gọi với một giá trị trả về có thể lặp lại từ tất cả các tác vụ, sẽ được lặp lại và mỗi giá trị được báo cáo

Đầu tiên, chúng ta phải cập nhật chức năng gọi lại để nhận một giá trị trả về có thể lặp lại thay vì một giá trị trả về duy nhất. Nó duyệt qua các giá trị trả về và báo cáo từng giá trị

Hàm result_callback() đã cập nhật được liệt kê bên dưới

1

2

3

4

5

# chức năng gọi lại kết quả

def result_callback(kết quả):

    # lần lặp trên tất cả các kết quả

    cho mục trong kết quả:

        print(f'Callback got. {item}')

Chức năng nhiệm vụ không cần bất kỳ thay đổi nào và có thể được sử dụng nguyên trạng

Tiếp theo, trong luồng chính, chúng ta sẽ gọi hàm map_async() để thực hiện 5 lệnh gọi hàm tác vụ với các giá trị nguyên từ 0 đến 9 và gọi hàm gọi lại sau khi tất cả các tác vụ được hoàn thành

1

2

3

.. .

# phát hành nhiệm vụ cho nhóm luồng

kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

Bạn có thể tìm hiểu thêm về hàm map_async() trong hướng dẫn

  • Cách sử dụng ThreadPool map_async() trong Python

Và đó là nó

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#Trăn Siêu Nhanh. com

# ví dụ về chức năng gọi lại cho map_async()

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    # lần lặp trên tất cả các kết quả

    cho mục trong kết quả:

        print(f'Callback got. {item}')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    # tạo giá trị

    giá trị = ngẫu nhiên()

    # báo cáo thư

    print(f'Task {identifier} đang thực thi)

   # khối trong giây lát

    ngủ(giá trị)

    # trả về giá trị đã tạo

    trả về giá trị

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Chạy ví dụ trước tiên khởi động ThreadPool với cấu hình mặc định

Sau đó, 5 tác vụ được cấp cho ThreadPool. Sau đó, luồng chính sẽ đóng nhóm và đợi các tác vụ đã phát hành hoàn thành

Các tác vụ thực thi trong ThreadPool. Mỗi tác vụ chạy, tạo một số ngẫu nhiên, báo cáo một tin nhắn, chặn và trả về một giá trị

Tất cả các nhiệm vụ đã hoàn thành và giá trị trả về của chúng được thu thập

Hàm gọi lại kết quả sau đó được gọi với một giá trị trả về có thể lặp lại. Iterable được duyệt qua và mỗi giá trị sau đó được báo cáo

Tất cả các tác vụ kết thúc và luồng chính thức dậy và tiếp tục, đóng chương trình

1

2

3

4

5

6

7

8

9

10

Nhiệm vụ 0 thực thi với 0. 38434699343509915

Nhiệm vụ 1 thực thi với 0. 9906470510678551

Nhiệm vụ 2 thực thi với 0. 5053311461831282

Nhiệm vụ 3 thực thi với 0. 6631948489144412

Nhiệm vụ 4 thực thi với 0. 6236711374365801

gọi lại đã nhận. 0. 38434699343509915

gọi lại đã nhận. 0. 9906470510678551

gọi lại đã nhận. 0. 5053311461831282

gọi lại đã nhận. 0. 6631948489144412

gọi lại đã nhận. 0. 6236711374365801

Tiếp theo, hãy xem một ví dụ về cách sử dụng hàm gọi lại với hàm starmap_async()

Bị choáng ngợp bởi các API đồng thời python?
Tìm sự giải thoát, tải xuống Bản đồ tư duy đồng thời Python MIỄN PHÍ của tôi

Hàm gọi lại ví dụ cho starmap_async()

Chúng ta có thể khám phá cách sử dụng gọi lại kết quả với ThreadPool khi thực hiện các tác vụ thông qua hàm starmap_async()

Trong ví dụ này, chúng tôi sẽ cập nhật ví dụ trước để hàm tác vụ đích nhận hai đối số thay vì một. Đối số thứ hai sẽ là một giá trị ngẫu nhiên được tạo sẽ được chuyển vào thay vì được tạo trong tác vụ. Một danh sách các đối số sẽ được chuẩn bị trong luồng chính chứa các mã định danh số nguyên và giá trị ngẫu nhiên, sau đó các tác vụ có nhiều đối số sẽ được thực hiện thông qua hàm starmap_async()

Đầu tiên, chúng ta phải cập nhật hàm task() để lấy số ngẫu nhiên làm đối số thứ hai và không tạo số như một phần của tác vụ

Hàm task() được cập nhật với những thay đổi này được liệt kê bên dưới

1

2

3

4

5

6

7

8

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh, value):

    # báo cáo thư

    print(f'Task {identifier} đang thực thi)

   # khối trong giây lát

    ngủ(giá trị)

    # trả về giá trị đã tạo

    trả về giá trị

Tiếp theo, trong luồng chính, trước tiên chúng ta sẽ tạo một danh sách các đối số. Mỗi mục trong danh sách sẽ là một bộ đối số cho một lệnh gọi hàm task() đích, chứa một số nguyên và một giá trị dấu phẩy động ngẫu nhiên được tạo

1

2

3

.. .

# chuẩn bị luận cứ

items = [(i, random()) for i in range(5)]

Sau đó, chúng tôi có thể phát hành 5 tác vụ thông qua starmap_async(), được định cấu hình để gọi hàm gọi lại sau khi tất cả các tác vụ đã phát hành đã hoàn thành

1

2

3

.. .

# phát hành nhiệm vụ cho nhóm luồng

kết quả = nhóm. starmap_async(nhiệm vụ, mục, callback=result_callback)

Bạn có thể tìm hiểu thêm về hàm starmap_async() trong bài hướng dẫn

  • Cách sử dụng ThreadPool starmap_async() trong Python

Và đó là nó

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#Trăn Siêu Nhanh. com

# ví dụ về chức năng gọi lại cho starmap_async()

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    # lần lặp trên tất cả các kết quả

    cho mục trong kết quả:

        print(f'Callback got. {item}')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh, value):

    # báo cáo thư

    print(f'Task {identifier} đang thực thi)

   # khối trong giây lát

    ngủ(giá trị)

    # trả về giá trị đã tạo

    trả về giá trị

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # chuẩn bị lập luận

        mặt hàng = [(i, random()) for i in range(5)]

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. starmap_async(nhiệm vụ, mục, callback=result_callback)

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Chạy ví dụ trước tiên khởi động ThreadPool với cấu hình mặc định

Sau đó, 5 tác vụ được cấp cho ThreadPool. Sau đó, luồng chính sẽ đóng nhóm và đợi các tác vụ đã phát hành hoàn thành

Các tác vụ thực thi trong ThreadPool. Mỗi tác vụ chạy, báo cáo một thông báo, chặn và trả về một giá trị

Tất cả các nhiệm vụ đã hoàn thành và giá trị trả về của chúng được thu thập

Hàm gọi lại kết quả sau đó được gọi với một giá trị trả về có thể lặp lại. Iterable được duyệt qua và mỗi giá trị sau đó được báo cáo

Tất cả các tác vụ kết thúc và luồng chính thức dậy và tiếp tục, đóng chương trình

1

2

3

4

5

6

7

8

9

10

Nhiệm vụ 0 thực thi với 0. 07269379108698282

Nhiệm vụ 1 thực thi với 0. 9359706773356883

Nhiệm vụ 2 thực thi với 0. 011172556495712471

Nhiệm vụ 3 thực thi với 0. 5027214064045555

Nhiệm vụ 4 thực thi với 0. 17518534128796326

gọi lại đã nhận. 0. 07269379108698282

gọi lại đã nhận. 0. 9359706773356883

gọi lại đã nhận. 0. 011172556495712471

gọi lại đã nhận. 0. 5027214064045555

gọi lại đã nhận. 0. 17518534128796326

Tiếp theo, chúng ta hãy xem luồng cụ thể được sử dụng để thực thi chức năng gọi lại

Chủ đề nào thực thi chức năng gọi lại

Chúng ta có thể khám phá luồng cụ thể được sử dụng để thực thi chức năng gọi lại kết quả

Trong ví dụ này, chúng tôi sẽ xác định một tác vụ nhận và báo cáo luồng hiện tại. Chúng tôi hy vọng đây là chủ đề công nhân. Chúng tôi cũng sẽ lấy và báo cáo chủ đề chính để tham khảo. Cuối cùng, chúng tôi sẽ nhận và báo cáo luồng hiện tại được sử dụng để thực hiện cuộc gọi lại kết quả

Đầu tiên, chúng ta có thể định nghĩa hàm gọi lại kết quả nhận và báo cáo chuỗi hiện tại

Nhớ lại rằng chúng ta có thể truy cập luồng hiện tại thông qua luồng. hàm current_thread() trả về một luồng. Ví dụ chủ đề

Điều này sẽ báo cáo chi tiết về luồng thực thi chức năng gọi lại, đáng chú ý nhất là tên và id

Hàm result_callback() bên dưới thực hiện điều này

1

2

3

4

5

6

# chức năng gọi lại kết quả

def result_callback(kết quả):

    # nhận chủ đề hiện tại

    thread = current_thread()

    # báo cáo chi tiết về chủ đề hiện tại

    print(f'Chủ đề gọi lại. {thread}')

Tiếp theo, chúng ta có thể định nghĩa một hàm tác vụ đích thực hiện điều tương tự. Nó nhận và báo cáo luồng được sử dụng để thực thi tác vụ

Hàm task() bên dưới thực hiện điều này

1

2

3

4

5

6

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    # nhận chủ đề hiện tại

    thread = current_thread()

    # báo cáo chi tiết về chủ đề hiện tại

    print(f'Task Thread. {thread}')

Cuối cùng, trong luồng chính, chúng tôi sẽ tạo và định cấu hình ThreadPool bằng trình quản lý bối cảnh, sau đó đưa ra một tác vụ duy nhất cho ThreadPool thông qua hàm apply_async(), được định cấu hình với hàm gọi lại kết quả

1

2

3

4

5

.. .

# tạo và cấu hình thread pool

với Nhóm luồng() như pool:

   # phát hành tác vụ cho nhóm luồng

    kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

Sau đó chúng tôi sẽ lấy và báo cáo các chi tiết của chủ đề hiện tại để tham khảo

1

2

3

4

5

.. .

# lấy chủ đề hiện tại

thread = current_thread()

# báo cáo chi tiết của chủ đề hiện tại

print(f'Chủ đề chính. {thread}')

Sau đó, chúng tôi sẽ đóng ThreadPool và đợi tác vụ đã ban hành hoàn thành

1

2

3

4

5

.. .

# đóng nhóm chủ đề

nhóm. đóng()

# đợi tất cả các nhiệm vụ hoàn thành

nhóm. tham gia()

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#Trăn Siêu Nhanh. com

# ví dụ báo cáo luồng thực thi chức năng gọi lại

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ luồng nhập current_thread

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    # nhận chủ đề hiện tại

    thread = current_thread()

    # báo cáo chi tiết về chủ đề hiện tại

    print(f'Chủ đề gọi lại. {thread}')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    # nhận chủ đề hiện tại

    thread = current_thread()

    # báo cáo chi tiết về chủ đề hiện tại

    print(f'Task Thread. {thread}')

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

        # nhận chủ đề hiện tại

        luồng = current_thread()

        # báo cáo chi tiết về chủ đề hiện tại

        in(f'Chủ đề chính. {thread}')

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Chạy ví dụ trước tiên khởi động ThreadPool

Chủ đề chính sau đó đưa ra một nhiệm vụ cho ThreadPool. Sau đó nó báo cáo chủ đề hiện tại

Trong trường hợp này, chúng ta có thể thấy rằng chương trình được thực thi bởi “MainThread” như chúng ta mong đợi

Bạn có thể tìm hiểu thêm về luồng chính trong hướng dẫn

  • Chủ đề chính trong Python là gì

Tiếp theo, nhiệm vụ được thực hiện

Trong trường hợp này, chúng ta có thể thấy rằng tác vụ được thực thi bởi một worker thread là một thể hiện của lớp DummyProcess và trong trường hợp này có tên là “Thread-1“

Cuối cùng, chức năng gọi lại kết quả được thực thi. Trong trường hợp này, chúng ta có thể thấy rằng cuộc gọi lại được thực thi bởi một chuỗi trợ giúp trong ThreadPool có tên là “Thread-11“

Lưu ý, tên và id luồng cụ thể sẽ khác nhau mỗi khi chương trình được chạy

1

2

3

Main Thread: <_MainThread(MainThread, started 4759727616)>

Task Thread:

Callback Thread:

Tiếp theo, hãy xem cách chúng ta có thể chia sẻ dữ liệu với chức năng gọi lại

Cách chia sẻ dữ liệu với chức năng gọi lại

Chúng ta có thể khám phá cách chia sẻ dữ liệu với chức năng gọi lại

Như chúng ta đã khám phá trong phần trước, cả mã nơi chúng ta tạo ThreadPool và phát hành các tác vụ cũng như hàm gọi lại đều được thực thi trong luồng chính của ứng dụng, ít nhất là trong các ví dụ này

Do đó, chúng ta có thể định nghĩa một biến toàn cục trong chương trình và chia sẻ nó và có sẵn cho hàm gọi lại

Chúng tôi sẽ xác định một biến toàn cục có giá trị dấu phẩy động ngẫu nhiên trong khoảng từ 0 đến 1. Sau đó, chúng tôi sẽ truy cập biến toàn cầu này trong hàm gọi lại, sau đó thay đổi nó. Khi tất cả các tác vụ đã hoàn thành, chúng tôi sẽ báo cáo lại biến toàn cầu và xác nhận rằng thay đổi đã được phản ánh

Điều này sẽ chứng minh cách hàm gọi lại có thể vừa truy cập vừa thay đổi các biến toàn cục từ chương trình

Đầu tiên, chúng ta có thể định nghĩa một hàm gọi lại khai báo biến toàn cục có tên là “data“, báo cáo giá trị, thay đổi nó, sau đó báo cáo giá trị đã thay đổi

Hàm result_callback() bên dưới thực hiện điều này

1

2

3

4

5

6

7

8

9

# chức năng gọi lại kết quả

def result_callback(kết quả):

    dữ liệu toàn cầu

    # báo cáo dữ liệu toàn cầu được chia sẻ từ chuỗi chính

    in(f'Dữ liệu gọi lại. {data}')

    # thay đổi

    dữ liệu = ngẫu nhiên()

   # báo cáo dữ liệu toàn cầu đã thay đổi

    print(f'Dữ liệu gọi lại ngay bây giờ. {data}')

Tiếp theo, chúng ta có thể định nghĩa một hàm nhiệm vụ mục tiêu chặn một lúc để mô phỏng nỗ lực tính toán

1

2

3

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    ngủ(1)

Cuối cùng, trong luồng chính, chúng ta có thể định nghĩa một biến toàn cục và gán cho nó một số ngẫu nhiên

1

2

3

.. .

# chuẩn bị dữ liệu toàn cầu được chia sẻ

dữ liệu = ngẫu nhiên()

Sau đó, chúng ta có thể tạo ThreadPool, đưa ra tác vụ được định cấu hình với kết quả gọi lại, sau đó đợi tác vụ hoàn thành

1

2

3

4

5

6

7

8

9

.. .

# tạo và cấu hình thread pool

với Nhóm luồng() như pool:

   # phát hành tác vụ cho nhóm luồng

    kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

    # đóng nhóm chuỗi

    nhóm. đóng()

    # đợi tất cả tác vụ hoàn tất

    nhóm. tham gia()

Sau đó, chúng tôi sẽ báo cáo biến toàn cục để xác nhận những thay đổi được thực hiện trong hàm gọi lại được phản ánh trong luồng chính

1

2

3

.. .

# báo cáo lại dữ liệu toàn cầu được chia sẻ

in(f'Dữ liệu chính. {data}')

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#Trăn Siêu Nhanh. com

# ví dụ về chia sẻ dữ liệu với chức năng gọi lại

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    dữ liệu toàn cầu

    # báo cáo dữ liệu toàn cầu được chia sẻ từ chuỗi chính

    in(f'Dữ liệu gọi lại. {data}')

    # thay đổi

    dữ liệu = ngẫu nhiên()

   # báo cáo dữ liệu toàn cầu đã thay đổi

    print(f'Dữ liệu gọi lại ngay bây giờ. {data}')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    ngủ(1)

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # chuẩn bị dữ liệu toàn cầu được chia sẻ

    dữ liệu = ngẫu nhiên()

    in(f'Dữ liệu chính. {data}')

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. apply_async(nhiệm vụ, args=(0,), callback=result_callback)

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

    # báo cáo lại dữ liệu toàn cầu được chia sẻ

    in(f'Dữ liệu chính. {data}')

Trước tiên, chạy ví dụ này sẽ tạo biến toàn cục và gán cho nó một số ngẫu nhiên, sau đó báo cáo giá trị

Tiếp theo, ThreadPool được tạo và tác vụ được thực hiện. Sau đó, luồng chính đợi tác vụ trong ThreadPool kết thúc

Tác vụ thực thi, chặn trong một giây, sau đó tác vụ kết thúc

Hàm gọi lại được gọi, mặc dù không có giá trị trả về. e. g. đối số của hàm sẽ là Không có

Hàm gọi lại khai báo biến toàn cục, sau đó báo cáo giá trị của nó. Chúng ta có thể thấy rằng giá trị được báo cáo khớp với giá trị được báo cáo từ luồng chính. Sau đó, nó gán một giá trị ngẫu nhiên mới cho biến toàn cục và báo cáo giá trị của nó

Chuỗi chính tiếp tục và báo cáo giá trị hiện tại của biến toàn cục. Chúng ta có thể thấy rằng luồng chính nhìn thấy giá trị đã thay đổi, khớp với giá trị đã được đặt trong hàm gọi lại

Điều này nêu bật cách dữ liệu có thể được cung cấp cho chức năng gọi lại và cách chức năng gọi lại có thể cung cấp dữ liệu cho luồng chính

Lưu ý, kết quả sẽ khác nhau mỗi khi chương trình được chạy do sử dụng các số ngẫu nhiên

1

2

3

4

Dữ liệu chính. 0. 2714984015082169

dữ liệu gọi lại. 0. 2714984015082169

Dữ liệu gọi lại ngay bây giờ. 0. 38990605438501535

Dữ liệu chính. 0. 38990605438501535

Tiếp theo, chúng ta hãy xem xét kỹ hơn khi một chức năng gọi lại được thực thi

Khi nào cuộc gọi lại được thực hiện

Chúng ta có thể khám phá khi chính xác chức năng gọi lại được gọi

Trong ví dụ này, chúng tôi sẽ báo cáo một thông báo trong luồng chính, trong tác vụ và trong chức năng gọi lại, sau đó sau khi tác vụ hoàn thành. Thứ tự của các thông báo được báo cáo sẽ đưa ra ý tưởng về thời điểm chính xác chức năng gọi lại được thực thi

Đầu tiên chúng ta có thể định nghĩa một hàm callback chỉ cần báo một thông báo là xong

1

2

3

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Gọi lại xong. ')

Tương tự, chúng ta có thể định nghĩa một chức năng nhiệm vụ báo cáo một thông báo rằng nó đã hoàn thành

1

2

3

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    in(f'Tác vụ {identifier} đã hoàn thành. ')

Chúng ta có thể tạo một ThreadPool và đưa ra năm tác vụ cho nhóm, được định cấu hình bằng chức năng gọi lại tùy chỉnh

1

2

3

4

5

.. .

# tạo và cấu hình thread pool

với Nhóm luồng() như pool:

   # phát hành tác vụ cho nhóm luồng

    kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

Sau đó, chúng tôi có thể báo cáo một tin nhắn, đợi các tác vụ hoàn thành, sau đó báo cáo một tin nhắn khác

1

2

3

4

5

6

.. .

# nhiệm vụ báo cáo được ban hành

in(f'Nhiệm vụ chính đã ban hành. ')

# chờ nhiệm vụ hoàn thành

kết quả. chờ đã()

in(f'Các nhiệm vụ chính đã hoàn thành. ')

Cuối cùng, hồ bơi có thể được đóng lại

1

2

3

4

5

.. .

# đóng nhóm chủ đề

nhóm. đóng()

# đợi tất cả các nhiệm vụ hoàn thành

nhóm. tham gia()

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#Trăn Siêu Nhanh. com

# ví dụ xác định thời điểm gọi lại kết quả

từ ngẫu nhiên nhập ngẫu nhiên

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Gọi lại xong. ')

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    in(f'Tác vụ {identifier} đã hoàn thành. ')

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

        # nhiệm vụ báo cáo được phát hành

        in(f'Nhiệm vụ chính đã ban hành. ')

        # chờ nhiệm vụ hoàn thành

        kết quả. chờ đã()

        in(f'Nhiệm vụ chính đã hoàn thành. ')

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Trước tiên, chạy ví dụ này sẽ tạo ThreadPool, sau đó đưa ra năm tác vụ

Sau đó, luồng chính báo cáo một thông báo rằng các tác vụ được phát hành, sau đó chặn cho đến khi các tác vụ được thực hiện

Tiếp theo, mỗi tác vụ thực thi và báo cáo một thông báo rằng chúng đã hoàn thành

Chức năng gọi lại sau đó được gọi và báo cáo rằng nó đã hoàn thành

Cuối cùng, tác vụ chính mở khóa, báo cáo một thông báo rằng tất cả các tác vụ đã hoàn thành và đóng ThreadPool

Điều này nhấn mạnh rằng cuộc gọi lại được gọi sau khi tất cả các nhiệm vụ đã ban hành được hoàn thành, nhưng trước khi người gọi biết rằng các nhiệm vụ đã được thực hiện. Đó là, cuộc gọi lại là một phần của nhiệm vụ từ quan điểm của người gọi đang chờ nhiệm vụ hoàn thành

1

2

3

4

5

6

7

8

Nhiệm vụ chính ban hành

Nhiệm vụ 0 đã hoàn thành

Nhiệm vụ 1 đã xong

Nhiệm vụ 2 đã xong

Nhiệm vụ 3 đã xong

Nhiệm vụ 4 đã hoàn thành

Gọi lại xong

Nhiệm vụ chính đã thực hiện

Tiếp theo, hãy xem điều gì sẽ xảy ra nếu có lỗi trong chức năng gọi lại

Điều gì xảy ra nếu một cuộc gọi lại làm tăng một ngoại lệ

Chúng ta có thể khám phá điều gì sẽ xảy ra nếu xảy ra lỗi trong hàm gọi lại kết quả

Trong ví dụ này, chúng tôi sẽ xác định hàm gọi lại kết quả đưa ra một ngoại lệ. Sau đó, chúng tôi sẽ phát hành nhiệm vụ như bình thường và đợi nó hoàn thành

Đầu tiên, chúng ta có thể xác định chức năng gọi lại tùy chỉnh báo cáo một thông báo sau đó đưa ra một ngoại lệ

1

2

3

4

5

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Gọi lại đang chạy. ')

   # lỗi

    tăng Ngoại lệ('Đã xảy ra sự cố'<)

Tiếp theo, chúng tôi sẽ xác định chức năng tác vụ mục tiêu chỉ báo cáo một thông báo

1

2

3

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    in(f'Tác vụ {identifier} đã hoàn thành. ')

Trong luồng chính, chúng tôi sẽ tạo ThreadPool, sau đó đưa ra năm tác vụ cho nhóm với cuộc gọi lại được định cấu hình

1

2

3

4

5

.. .

# tạo và cấu hình thread pool

với Nhóm luồng() như pool:

   # phát hành tác vụ cho nhóm luồng

    kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

Sau đó, luồng chính sẽ đợi các tác vụ hoàn thành, sau đó đóng nhóm luồng

1

2

3

4

5

6

7

8

9

10

.. .

# nhiệm vụ báo cáo được ban hành

in(f'Nhiệm vụ chính đã ban hành. ')

# chờ nhiệm vụ hoàn thành

kết quả. chờ đã()

in(f'Các nhiệm vụ chính đã hoàn thành. ')

# đóng nhóm chủ đề

nhóm. đóng()

# đợi tất cả các nhiệm vụ hoàn thành

nhóm. tham gia()

Liên kết điều này lại với nhau, ví dụ hoàn chỉnh được liệt kê bên dưới

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#Trăn Siêu Nhanh. com

# ví dụ về việc xác định điều gì sẽ xảy ra nếu một ngoại lệ được đưa ra trong kết quả gọi lại

từ thời gian nhập ngủ

từ đa xử lý. nhóm nhập ThreadPool

 

# chức năng gọi lại kết quả

def result_callback(kết quả):

    print(f'Gọi lại đang chạy. ')

   # lỗi

    tăng Ngoại lệ('Đã xảy ra sự cố'<)

 

# tác vụ được thực hiện trong chuỗi công nhân

def nhiệm vụ(mã định danh):

    in(f'Tác vụ {identifier} đã hoàn thành. ')

 

#bảo vệ điểm vào

if __name__ == '__main__'.

    # tạo và định cấu hình nhóm luồng

    với ThreadPool() as pool:

        # phát hành tác vụ cho nhóm chuỗi

        kết quả = nhóm. map_async(nhiệm vụ, phạm vi(5), callback=result_callback)

        # nhiệm vụ báo cáo được phát hành

        in(f'Nhiệm vụ chính đã ban hành. ')

        # chờ nhiệm vụ hoàn thành

        kết quả. chờ đã()

        in(f'Nhiệm vụ chính đã hoàn thành. ')

        # đóng nhóm chủ đề

        nhóm. đóng()

        # đợi tất cả các tác vụ hoàn thành

        nhóm. tham gia()

Chạy ví dụ trước tiên sẽ tạo ThreadPool

Sau đó, nó đưa ra 5 nhiệm vụ và đợi chúng hoàn thành

Mỗi tác vụ thực thi, báo cáo một thông báo như bình thường

Chức năng gọi lại sau đó được gọi sau khi tất cả các tác vụ kết thúc. Một thông báo được báo cáo, sau đó một ngoại lệ được đưa ra

Sau đó, ngoại lệ xuất hiện để giải phóng luồng trợ giúp trong ThreadPool. Điều này rất có thể phá vỡ ThreadPool

Luồng chính trong khối luồng chính mãi mãi chờ các tác vụ đã phát hành hoàn thành. Các tác vụ không bao giờ hoàn thành vì chức năng gọi lại không bao giờ hoàn thành thành công

Điều này nhấn mạnh rằng phải cẩn thận trong chức năng gọi lại vì một lỗi trong cuộc gọi lại có thể khiến ứng dụng ngừng hoạt động

Lưu ý, bạn sẽ phải tự chấm dứt chương trình, e. g. Kiểm soát-C

1

2

3

4

5

6

7

8

9

10

11

Nhiệm vụ chính ban hành

Nhiệm vụ 0 đã hoàn thành

Nhiệm vụ 1 đã xong

Nhiệm vụ 2 đã xong

Nhiệm vụ 3 đã xong

Nhiệm vụ 4 đã hoàn thành

gọi lại đang chạy

Ngoại lệ trong chủ đề Chủ đề-11

Traceback (cuộc gọi gần đây nhất cuối cùng)

  

Ngoại lệ. Điều xấu đã xảy ra

Câu hỏi thường gặp

Phần này liệt kê các câu hỏi phổ biến về các cuộc gọi lại kết quả được sử dụng với các tác vụ không đồng bộ trong ThreadPool

Bạn có câu hỏi nào không?
Hãy cho tôi biết dưới đây

Gọi lại là gì?

Gọi lại là một chức năng được gọi tự động sau khi tất cả các tác vụ không đồng bộ được cấp cho ThreadPool trong một lô đã hoàn thành

Khi nào tôi nên sử dụng gọi lại?

Bạn có thể sử dụng chức năng gọi lại khi phát hành các tác vụ không đồng bộ cho ThreadPool

Hàm gọi lại có thể được sử dụng để xử lý kết quả của các nhiệm vụ đã ban hành, chẳng hạn như báo cáo, lưu trữ hoặc thu thập kết quả của các nhiệm vụ đã ban hành

Các chức năng gọi lại sẽ không mất nhiều thời gian để thực thi vì chúng sẽ chiếm tài nguyên của ThreadPool

Cuộc gọi lại nhận được đối số nào?

Hàm gọi lại sẽ nhận giá trị trả về từ tác vụ hoặc các tác vụ được cấp cho ThreadPool

Trong trường hợp apply_async(), đối số sẽ là một giá trị duy nhất

Trong trường hợp map_async() và starmap_async(), đối số sẽ là giá trị trả về có thể lặp lại

Điều gì xảy ra nếu Hàm tác vụ không trả về giá trị?

Hàm gọi lại đã định cấu hình sẽ được gọi ngay cả khi hàm tác vụ đích của bạn không trả về giá trị

Trong trường hợp đó, đối số của hàm gọi lại sẽ là giá trị trả về mặc định là Không có

Chủ đề nào thực thi chức năng gọi lại?

Chức năng gọi lại được thực thi trong một luồng trợ giúp của ThreadPool trong quy trình chính hoặc quy trình mà ThreadPool được tạo và các tác vụ được đưa ra

Kết quả gọi lại có được gọi trước khi gọi lại lỗi không?

KHÔNG

Nếu ít nhất một tác vụ phát sinh lỗi, thì hàm gọi lại kết quả sẽ không được gọi và thay vào đó, hàm gọi lại lỗi sẽ được gọi

Tôi có thể phát hành các tác vụ tiếp theo từ cuộc gọi lại kết quả không?

Đúng

Có thể truy cập ThreadPool thông qua một biến toàn cục và các tác vụ tiếp theo có thể được thực hiện trực tiếp từ bên trong chức năng gọi lại

Bạn có thể gọi một biến toàn cục trong hàm Python không?

Mọi người đều có thể sử dụng biến toàn cục, cả bên trong và bên ngoài hàm .

Có nên sử dụng các biến toàn cục trong Python không?

Việc sử dụng biến toàn cục trong python được coi là thông lệ không tốt và thường nên tránh . Thay vào đó, người dùng có thể thử và sử dụng tham số để truyền giá trị vào hàm hoặc trả về giá trị để lấy giá trị đó.

Tại sao chúng ta không nên sử dụng biến toàn cục trong Python?

Lý do các biến toàn cục không tốt là vì chúng cho phép các chức năng có các tác dụng phụ ẩn (không rõ ràng, đáng ngạc nhiên, khó phát hiện, khó chẩn đoán), dẫn đến sự gia tăng . .

Làm cách nào bạn có thể truy cập một biến toàn cục bên trong hàm nếu hàm có một biến có cùng tên?

Để truy cập biến toàn cục trong hàm, nếu hàm đó có biến cục bộ trùng tên, chúng ta dùng từ khóa toàn cục trước tên biến.