Hướng dẫn python end loop after time - python kết thúc vòng lặp sau thời gian

Câu trả lời của Petr Krampl là tốt nhất theo quan điểm của tôi, nhưng cần phải nói nhiều hơn về bản chất của các vòng lặp và cách tối ưu hóa việc sử dụng hệ thống. Những người mới bắt đầu xảy ra trên chủ đề này có thể bị nhầm lẫn thêm bởi các lỗi logic và thuật toán trong câu hỏi và câu trả lời hiện có.

Đầu tiên, chúng ta hãy xem mã của bạn làm như bạn đã viết ban đầu:

while True:
    test = 0
    if test == 5:
        break
    test = test - 1

Nếu bạn nói while True trong bối cảnh vòng lặp, thông thường ý định của bạn là ở lại trong vòng lặp mãi mãi. Nếu đó không phải là ý định của bạn, bạn nên xem xét các tùy chọn khác cho cấu trúc của vòng lặp. Petr KRAMPL đã cho bạn thấy một cách hoàn toàn hợp lý để xử lý điều này rõ ràng hơn nhiều đối với người khác có thể đọc mã của bạn. Ngoài ra, bạn sẽ rõ ràng hơn với bạn vài tháng sau nếu bạn cần xem lại mã của mình để thêm hoặc sửa chữa một cái gì đó. Mã được viết tốt là một phần của tài liệu của bạn. Thường có nhiều cách để làm mọi việc, nhưng điều đó không làm cho tất cả các cách có giá trị như nhau trong tất cả các bối cảnh.

test = 0
while True:
    test = test - 1
    if test == 5:
        break
0 là một ví dụ tốt về điều này, đặc biệt là trong bối cảnh này.

Tiếp theo, chúng tôi sẽ xem xét lỗi thuật toán trong mã ban đầu của bạn. Điều đầu tiên bạn làm trong vòng lặp là gán 0 cho

test = 0
while True:
    test = test - 1
    if test == 5:
        break
1. Điều tiếp theo bạn làm là kiểm tra xem giá trị của
test = 0
while True:
    test = test - 1
    if test == 5:
        break
1 là 5, điều này sẽ không bao giờ xảy ra trừ khi bạn có nhiều luồng sửa đổi cùng một vị trí bộ nhớ. Chủ đề không nằm trong phạm vi cho cuộc thảo luận này, nhưng điều đáng chú ý là mã có thể hoạt động về mặt kỹ thuật, nhưng ngay cả với nhiều luồng sẽ bị thiếu rất nhiều, ví dụ: Semaphores. Dù sao, bạn sẽ ngồi trong vòng lặp này mãi mãi bất kể thực tế là Sentinel đang buộc một vòng lặp vô hạn.

Tuyên bố

test = 0
while True:
    test = test - 1
    if test == 5:
        break
3 là vô ích bất kể nó làm gì vì biến được đặt lại ở đầu lần lặp tiếp theo của vòng lặp. Ngay cả khi bạn đã thay đổi nó thành
test = 0
while True:
    test = test - 1
    if test == 5:
        break
4, vòng lặp vẫn sẽ là vô hạn vì giá trị được đặt lại mỗi lần. Nếu bạn di chuyển câu lệnh khởi tạo bên ngoài vòng lặp, thì ít nhất nó sẽ có cơ hội thoát. Những gì bạn có thể dự định là một cái gì đó như thế này:

test = 0
while True:
    test = test - 1
    if test == 5:
        break

Thứ tự của các câu lệnh trong vòng lặp phụ thuộc vào logic của chương trình của bạn. Nó sẽ hoạt động theo một trong hai thứ tự, mặc dù, đó là điểm chính.

Vấn đề tiếp theo là lỗi logic tiềm năng và có thể xảy ra khi bắt đầu từ 0, liên tục trừ 1, sau đó so sánh với một số dương. Vâng, có những lúc đây thực sự có thể là những gì bạn dự định làm miễn là bạn hiểu những hàm ý, nhưng đây rất có thể không phải là những gì bạn dự định. Các phiên bản mới hơn của Python sẽ không bao quanh khi bạn đạt đến 'đáy' của phạm vi của một số nguyên như C và các ngôn ngữ khác. Nó sẽ cho phép bạn tiếp tục trừ 1 cho đến khi bạn điền bộ nhớ có sẵn trên hệ thống của mình hoặc ít nhất là những gì được phân bổ cho quy trình của bạn. Nhìn vào tập lệnh sau và kết quả:

test = 0

while True:
    test  -= 1

    if test % 100 == 0:
        print "Test = %d" % test

    if test == 5:
        print "Test = 5"
        break

Mà sản xuất điều này:

Test = -100
Test = -200
Test = -300
Test = -400
...
Test = -21559000
Test = -21559100
Test = -21559200
Test = -21559300
...

Giá trị của

test = 0
while True:
    test = test - 1
    if test == 5:
        break
1 sẽ không bao giờ là 5, vì vậy vòng lặp này sẽ không bao giờ thoát.

Để thêm vào câu trả lời của Petr Krampl, đây là phiên bản có lẽ gần với những gì bạn thực sự dự định ngoài việc thoát khỏi vòng lặp sau một khoảng thời gian nhất định:

import time

test = 0
timeout = 300   # [seconds]

timeout_start = time.time()

while time.time() < timeout_start + timeout:
    if test == 5:
        break
    test -= 1

Nó vẫn sẽ không bị phá vỡ dựa trên giá trị của

test = 0
while True:
    test = test - 1
    if test == 5:
        break
1, nhưng đây là một vòng lặp hoàn toàn hợp lệ với điều kiện ban đầu hợp lý. Kiểm tra ranh giới hơn nữa có thể giúp bạn tránh thực hiện một vòng lặp rất dài mà không có lý do, ví dụ: Kiểm tra xem giá trị của bài kiểm tra nhỏ hơn 5 khi nhập vòng lặp, điều này sẽ ngay lập tức phá vỡ vòng lặp.


Một điều khác nên được đề cập rằng không có câu trả lời nào khác đã được giải quyết. Đôi khi khi bạn lặp như thế này, bạn có thể không muốn tiêu thụ CPU trong toàn bộ thời gian được quy định. Ví dụ: giả sử bạn đang kiểm tra giá trị của một cái gì đó thay đổi mỗi giây. Nếu bạn không giới thiệu một số loại độ trễ, bạn sẽ sử dụng mọi chu kỳ CPU có sẵn được phân bổ cho quy trình của bạn. Điều đó là tốt nếu cần thiết, nhưng thiết kế tốt sẽ cho phép rất nhiều chương trình chạy song song trên hệ thống của bạn mà không làm quá tải các tài nguyên có sẵn. Một tuyên bố về giấc ngủ đơn giản sẽ giải phóng phần lớn các chu kỳ CPU được phân bổ cho quy trình của bạn để các chương trình khác có thể hoạt động.

Ví dụ sau đây không hữu ích, nhưng nó chứng minh khái niệm này. Giả sử bạn muốn in một cái gì đó mỗi giây. Một cách để làm điều đó sẽ như thế này:

import time

tCurrent = time.time()

while True:
    if time.time() >= tCurrent + 1:
        print "Time = %d" % time.time()
        tCurrent = time.time()

Đầu ra sẽ là thế này:

Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799

Và quá trình sử dụng CPU sẽ trông như thế này:

Hướng dẫn python end loop after time - python kết thúc vòng lặp sau thời gian

Đó là một lượng lớn việc sử dụng CPU để thực hiện về cơ bản không có việc làm. Mã này đẹp hơn nhiều so với phần còn lại của hệ thống:

import time

tCurrent = time.time()

while True:
    time.sleep(0.25) # sleep for 250 milliseconds
    if time.time() >= tCurrent + 1:
        print "Time = %d" % time.time()
        tCurrent = time.time()

Đầu ra là như nhau:

Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799

Và việc sử dụng CPU là cách, cách thấp hơn:

Hướng dẫn python end loop after time - python kết thúc vòng lặp sau thời gian