Trong thực tế, Timer có lẽ là cách đơn giản nhất để thực hiện những gì bạn muốn.
Mã này sẽ làm như sau:
- Sau 1 giây, nó in "arg1 arg2"
- Sau 2 giây, nó in "cú cú cú"
===
from threading import Timer
def twoArgs(arg1,arg2):
print arg1
print arg2
print ""
def nArgs(*args):
for each in args:
print each
#arguments:
#how long to wait (in seconds),
#what function to call,
#what gets passed in
r = Timer(1.0, twoArgs, ("arg1","arg2"))
s = Timer(2.0, nArgs, ("OWLS","OWLS","OWLS"))
r.start()
s.start()
===
Mã trên sẽ rất có thể giải quyết được vấn đề của bạn.
Nhưng! Có cách khác, không sử dụng đa luồng. Nó hoạt động nhiều hơn như Javascript, đó là đơn luồng.
Đối với phiên bản một chuỗi này, tất cả những gì bạn cần làm là lưu trữ hàm và các đối số của hàm trong đối tượng, cùng với thời gian chạy hàm.
Khi bạn có đối tượng chứa lệnh gọi hàm và thời gian chờ, chỉ cần kiểm tra định kỳ xem chức năng đã sẵn sàng để thực thi hay chưa.
Cách đúng để thực hiện việc này là tạo một priority queue để lưu trữ tất cả các chức năng mà chúng tôi muốn chạy trong tương lai, như được hiển thị trong mã bên dưới.
Cũng giống như trong Javascript, cách tiếp cận này không đảm bảo rằng chức năng sẽ được chạy chính xác về thời gian. Một hàm cần một thời gian rất dài để chạy sẽ làm chậm các hàm sau nó. Nhưng nó đảm bảo rằng một chức năng sẽ được chạy không sớm hơn so với thời gian chờ của nó.
Mã này sẽ làm như sau:
- Sau 1 giây, nó in "20"
- Sau 2 giây, nó in "132"
- Sau 3 giây, nó tha.
===
from datetime import datetime, timedelta
import heapq
# just holds a function, its arguments, and when we want it to execute.
class TimeoutFunction:
def __init__(self, function, timeout, *args):
self.function = function
self.args = args
self.startTime = datetime.now() + timedelta(0,0,0,timeout)
def execute(self):
self.function(*self.args)
# A "todo" list for all the TimeoutFunctions we want to execute in the future
# They are sorted in the order they should be executed, thanks to heapq
class TodoList:
def __init__(self):
self.todo = []
def addToList(self, tFunction):
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def executeReadyFunctions(self):
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
while tFunction and datetime.now() > tFunction.startTime:
#execute all the functions that are ready
tFunction.execute()
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
else:
tFunction = None
if tFunction:
#this one's not ready yet, push it back on
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def singleArgFunction(x):
print str(x)
def multiArgFunction(x, y):
#Demonstration of passing multiple-argument functions
print str(x*y)
# Make some TimeoutFunction objects
# timeout is in milliseconds
a = TimeoutFunction(singleArgFunction, 1000, 20)
b = TimeoutFunction(multiArgFunction, 2000, *(11,12))
c = TimeoutFunction(quit, 3000, None)
todoList = TodoList()
todoList.addToList(a)
todoList.addToList(b)
todoList.addToList(c)
while True:
todoList.executeReadyFunctions()
===
Trong thực tế, bạn có thể sẽ nhiều hơn xảy ra ở chỗ vòng lặp while hơn là chỉ kiểm tra nếu chức năng thời gian chờ của bạn đã sẵn sàng để đi. Bạn có thể đang bỏ phiếu cho đầu vào của người dùng, kiểm soát một số phần cứng, đọc dữ liệu, v.v.
Đó không phải là những gì 'setTimeout' thực hiện trong JavaScript. Điều đó có nghĩa là xếp hàng một hàm để thực thi sau này (tức là khi hết thời gian chờ). –
Vâng ... Bạn nói đúng. Nhưng tôi chỉ muốn đưa ra ý tưởng về những gì tôi muốn mà tôi không thấy cần phải hoàn toàn chính xác về mặt kỹ thuật. – brunoais
Tốt nhất bạn có thể làm là thử một cái gì đó với chủ đề. –