2015-04-21 30 views

Trả lời

6

Sử dụng một sợi chứa một vòng lặp

from threading import Thread 
import time 

def background_task(): 
    while not background_task.cancelled: 
     self.mqConn.heartbeat_tick() 
     time.sleep(30) 
background_task.cancelled = False 

t = Thread(target=background_task) 
t.start() 

background_task.cancelled = True 

Ngoài ra, bạn có thể phân lớp hẹn giờ, để làm hủy dễ dàng:

from threading import Timer 

class RepeatingTimer(Timer): 
    def run(self): 
     while not self.finished.is_set(): 
      self.function(*self.args, **self.kwargs) 
      self.finished.wait(self.interval) 


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick) 
t.start() # every 30 seconds, call heartbeat_tick 

# later 
t.cancel() # cancels execution 
+1

Nó có thể là quan trọng để đề cập đến rằng đây * sẽ không * thực hiện mỗi 30 giây nếu 'heartbeat_tick()' mất một số lượng đáng kể thời gian – goncalopp

+0

Yep, điều này sẽ ít nhất 30 giây mỗi lần. Tối đa 30 giây là khó hơn một chút. – Eric

+1

Nếu chức năng tiền cảnh của bạn bị ràng buộc CPU, liệu luồng nền sẽ được ngăn chặn từ khi GIL thực thi? –

2

Một cách để làm điều này là sử dụng khuôn khổ circuits ứng dụng như thế này:

from circuits import Component, Event, Timer 


class App(Component): 

    def init(self, mqConn): 
     self.mqConn = mqConn 
     Timer(30, Event.create("heartbeat"), persist=True).register(self) 

    def heartbeat(self): 
     self.mqConn.heartbeat_tick() 


App().run() 

Lưu ý: Tôi là tác giả của các mạch :)

Đây chỉ là một ý tưởng cơ bản và cấu trúc - Bạn sẽ cần phải điều chỉnh cho phù hợp với ứng dụng và yêu cầu chính xác của bạn!

1

Hoặc bạn có thể sử dụng lớp Timer trong mô-đun threading :

from threading import Timer 

def hello(): 
    print "hello, world" 

t = Timer(30.0, hello) 
t.start() # after 30 seconds, "hello, world" will be printed 
t.cancel() # cancels execution, this only works before the 30 seconds is elapsed 

Điều này sẽ không bắt đầu sau mỗi x giây, thay vì nó trì hoãn luồng để thực hiện trong x giây. Nhưng bạn vẫn có thể đặt nó trong một vòng lặp và sử dụng t.is_alive() để xem trạng thái của nó.

+0

Vòng lặp sẽ đi đâu? – Eric

+0

Điều đó phụ thuộc vào trường hợp sử dụng? – Joe

+0

Điều đó cũng không cần phải nằm trong một chủ đề nền? – Eric

2

Theo dõi nhanh Eric câu trả lời: bạn không thể phân lớp Timer, vì nó thực sự là một hàm bao bọc ánh sáng xung quanh lớp thực: _Timer. Nếu bạn thực hiện, bạn sẽ gặp phải vấn đề nảy sinh trong this post.

Sử dụng _Timer thay vì sửa chữa nó:

from threading import _Timer 

class RepeatingTimer(_Timer): 
    def run(self): 
     while not self.finished.is_set(): 
      self.function(*self.args, **self.kwargs) 
      self.finished.wait(self.interval) 


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick) 
t.start() # every 30 seconds, call heartbeat_tick 

# later 
t.cancel() # cancels execution 
Các vấn đề liên quan