Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?

Tôi cần phải đợi trong một kịch bản cho đến khi một số điều kiện nhất định trở thành sự thật?

Tôi biết tôi có thể tự mình thực hiện sự kiện của mình bằng các biến điều kiện và bạn bè, nhưng tôi không muốn trải qua tất cả những rắc rối khi thực hiện nó, vì một số thay đổi thuộc tính đối tượng đến từ luồng bên ngoài trong thư viện C ++ được bọc (Boost.Python), Vì vậy, tôi không thể chiếm quyền điều khiển

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
5 trong một lớp và đặt một biến điều kiện ở đó, khiến tôi cố gắng tạo và báo hiệu một biến điều kiện trăn từ C ++ hoặc bọc một bản địa và chờ nó trong Python, cả hai Âm thanh khó hiểu, không cần thiết phải phức tạp và nhàm chán.

Có một cách nào dễ dàng hơn để làm điều đó, ngăn chặn việc bỏ phiếu liên tục điều kiện?

Lý tưởng nhất là nó sẽ nằm dọc theo dòng

res = wait_until(lambda: some_predicate, timeout)
if (not res):
    print 'timed out'

Khi được hỏi ngày 7 tháng 5 năm 2010 lúc 2:33May 7, 2010 at 2:33

Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?

Thật không may, khả năng duy nhất để đáp ứng các ràng buộc của bạn là thăm dò định kỳ, ví dụ ....:

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False

hoặc những thứ tương tự. Điều này có thể được tối ưu hóa theo nhiều cách nếu

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
6 có thể bị phân tách (ví dụ: nếu nó được biết là
import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
7 của một số điều khoản, đặc biệt là nếu một số điều khoản lần lượt được tối ưu hóa bằng cách phát hiện qua
import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
8 hoặc bất cứ điều gì, v.v.) Nhưng trong các thuật ngữ chung mà bạn yêu cầu, cách tiếp cận không hiệu quả này là lối thoát duy nhất.

Mariusz Jamro

29.7K24 Huy hiệu vàng111 Huy hiệu bạc154 Huy hiệu đồng24 gold badges111 silver badges154 bronze badges

Đã trả lời ngày 7 tháng 5 năm 2010 lúc 2:57May 7, 2010 at 2:57

Alex Martellialex MartelliAlex Martelli

829K164 Huy hiệu vàng1205 Huy hiệu bạc1385 Huy hiệu Đồng164 gold badges1205 silver badges1385 bronze badges

4

Một gói đẹp khác là

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
9 - https://pypi.org/project/waiting/

install:

pip install waiting

Cách sử dụng: Bạn vượt qua một hàm sẽ được gọi mỗi lần là điều kiện, thời gian chờ và (điều này rất hữu ích) bạn có thể vượt qua mô tả cho sự chờ đợi, sẽ được hiển thị nếu bạn nhận được thời gian.

sử dụng chức năng:

from waiting import wait


def is_something_ready(something):
    if something.ready():
        return True
    return False


# wait for something to be ready
something = # whatever

wait(lambda: is_something_ready(something), timeout_seconds=120, waiting_for="something to be ready")

# this code will only execute after "something" is ready
print("Done")

Lưu ý: Hàm phải trả về Boolean - Đúng khi chờ đợi kết thúc, sai nếu không

Đã trả lời ngày 17 tháng 12 năm 2019 lúc 7:23Dec 17, 2019 at 7:23

3

Đây là một giải pháp khác. Mục tiêu là thực hiện các chủ đề để chờ đợi nhau trước khi thực hiện một số công việc theo thứ tự rất chính xác. Công việc có thể mất thời gian không xác định. Bỏ phiếu liên tục không tốt vì hai lý do: nó ăn thời gian CPU và hành động không bắt đầu ngay sau khi điều kiện được đáp ứng.

class Waiter():

    def __init__(self, init_value):
        self.var = init_value
        self.var_mutex = threading.Lock()
        self.var_event = threading.Event()

    def WaitUntil(self, v):
        while True:
            self.var_mutex.acquire()
            if self.var == v:
                self.var_mutex.release()
                return # Done waiting
            self.var_mutex.release()
            self.var_event.wait(1) # Wait 1 sec

    def Set(self, v):
        self.var_mutex.acquire()
        self.var = v
        self.var_mutex.release()
        self.var_event.set() # In case someone is waiting
        self.var_event.clear()

Và cách để kiểm tra nó

class TestWaiter():

    def __init__(self):
        self.waiter = Waiter(0)
        threading.Thread(name='Thread0', target=self.Thread0).start()
        threading.Thread(name='Thread1', target=self.Thread1).start()
        threading.Thread(name='Thread2', target=self.Thread2).start()

    def Thread0(self):
        while True:
            self.waiter.WaitUntil(0)
            # Do some work
            time.sleep(np.random.rand()*2)
            self.waiter.Set(1)

    def Thread1(self):
        while True:
            self.waiter.WaitUntil(1)
            # Do some work
            time.sleep(np.random.rand())
            self.waiter.Set(2)

    def Thread2(self):
        while True:
            self.waiter.WaitUntil(2)
            # Do some work
            time.sleep(np.random.rand()/10)
            self.waiter.Set(0)

Người phục vụ cho đa xử lý:

import multiprocessing as mp
import ctypes

class WaiterMP():
    def __init__(self, init_value, stop_value=-1):
        self.var = mp.Value(ctypes.c_int, init_value)
        self.stop_value = stop_value
        self.event = mp.Event()

    def Terminate(self):
        self.Set(self.stop_value)

    def Restart(self):
        self.var.value = self.init_value

    def WaitUntil(self, v):
        while True:
            if self.var.value == v or self.var.value == self.stop_value:
                return
            # Wait 1 sec and check aiagn (in case event was missed)
            self.event.wait(1)

    def Set(self, v):
        exit = self.var.value == self.stop_value
        if not exit: # Do not set var if threads are exiting
            self.var.value = v
        self.event.set() # In case someone is waiting
        self.event.clear()

Hãy bình luận nếu đây vẫn không phải là giải pháp tốt nhất.

Đã trả lời ngày 25 tháng 5 năm 2020 lúc 16:05May 25, 2020 at 16:05

AlexalexAlex

811 Huy hiệu bạc2 Huy hiệu đồng1 silver badge2 bronze badges

2

Về cơ bản, bạn đã trả lời câu hỏi của riêng bạn: Không.

Vì bạn đang xử lý các thư viện bên ngoài trong Boost.Python, có thể thay đổi các đối tượng khi giải trí, bạn cần phải có những thói quen đó gọi một trình xử lý sự kiện làm mới hoặc làm việc với một điều kiện.

Đã trả lời ngày 7 tháng 5 năm 2010 lúc 2:36May 7, 2010 at 2:36

Yann Raminyann RaminYann Ramin

32,7k3 huy hiệu vàng57 Huy hiệu bạc81 Huy hiệu đồng3 gold badges57 silver badges81 bronze badges

Đây là sự mở rộng luồng cho giải pháp của Alex:

import time
import threading

# based on https://stackoverflow.com/a/2785908/1056345                                                                                                                                                                                                                                                                         
def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
    must_end = time.time() + timeout
    while time.time() < must_end:
        if somepredicate(*args, **kwargs):
            return True
        time.sleep(period)
    return False

def wait_until_par(*args, **kwargs):
    t = threading.Thread(target=wait_until, args=args, kwargs=kwargs)
    t.start()
    print ('wait_until_par exits, thread runs in background')

def test():
    print('test')

wait_until_par(test, 5)

Đã trả lời ngày 4 tháng 8 năm 2017 lúc 4:16Aug 4, 2017 at 4:16

Kavaklıoğlucan KavaklıoğluCan Kavaklıoğlu

4871 Huy hiệu vàng7 Huy hiệu bạc12 Huy hiệu đồng1 gold badge7 silver badges12 bronze badges

Từ góc độ tính toán, đôi khi phải có một kiểm tra cho tất cả các điều kiện ở đâu đó. Nếu bạn có hai phần mã, một phần tạo ra các thay đổi điều kiện và phần còn lại nên được thực thi khi một số là đúng, bạn có thể thực hiện như sau:

Có mã thay đổi các điều kiện, giả sử, chủ đề chính và mã nên được khởi chạy khi một số điều kiện là đúng, trong một luồng công nhân.

from threading import Thread,Event

locker = Event()

def WhenSomeTrue(locker):
    locker.clear() # To prevent looping, see manual, link below
    locker.wait(2.0) # Suspend the thread until woken up, or 2s timeout is reached
    if not locker.is_set(): # when is_set() false, means timeout was reached
        print('TIMEOUT')
    else:
    #
    # Code when some conditions are true
    #
worker_thread = Thread(target=WhenSomeTrue, args=(locker,))
worker_thread.start()

cond1 = False
cond2 = False
cond3 = False

def evaluate():
    true_conditions = 0

    for i in range(1,4):
        if globals()["cond"+str(i)]: #access a global condition variable one by one
            true_conditions += 1     #increment at each true value
    if true_conditions > 1:
        locker.set() # Resume the worker thread executing the else branch
    #Or just if true_conditions > 1: locker.set();
    #true_conditions would need be incremented when 'True' is written to any of those variables

#
# some condition change code
#
evaluate()

Để biết thêm thông tin liên quan đến phương pháp này, hãy truy cập: https://docs.python.org/3/l Library/threading.html#event-objects

Đã trả lời ngày 27 tháng 5 năm 2021 lúc 22:42May 27, 2021 at 22:42

Giải pháp đề xuất:

def wait_until(delegate, timeout: int):
    end = time.time() + timeout
    while time.time() < end:
        if delegate():
            return True
        else:
            time.sleep(0.1)
    return False

Cách sử dụng:

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
0

Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?

Asclepius

53K16 Huy hiệu vàng154 Huy hiệu bạc137 Huy hiệu đồng16 gold badges154 silver badges137 bronze badges

Đã trả lời ngày 9 tháng 7 năm 2019 lúc 17:11Jul 9, 2019 at 17:11

Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?

Tôi đã sử dụng nó trong mã của mình:

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
1

Hi vọng điêu nay co ich

Đã trả lời ngày 29 tháng 8 lúc 14:12Aug 29 at 14:12

Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?

Điều này làm việc cho tôi

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
2

Điều này là để chờ tín hiệu trong khi đảm bảo giới hạn thời gian là 1 giây

Yamaneko

3.3232 Huy hiệu vàng36 Huy hiệu bạc56 Huy hiệu Đồng2 gold badges36 silver badges56 bronze badges

Đã trả lời ngày 2 tháng 2 năm 2019 lúc 9:37Feb 2, 2019 at 9:37

Đây là cách:

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
3

Đã trả lời ngày 28 tháng 6 năm 2021 lúc 21:29Jun 28, 2021 at 21:29

1

Đây là mã của tôi tôi đã sử dụng trong một trong các dự án của tôi:

import time

def wait_until(somepredicate, timeout, period=0.25, *args, **kwargs):
  mustend = time.time() + timeout
  while time.time() < mustend:
    if somepredicate(*args, **kwargs): return True
    time.sleep(period)
  return False
4

Hy vọng nó giúp

Đã trả lời ngày 15 tháng 3 năm 2020 lúc 10:05Mar 15, 2020 at 10:05

Hướng dẫn how do you wait until something in python? - làm thế nào để bạn chờ đợi cho đến khi một cái gì đó trong python?