2013-03-17 5 views
2

함수에서 2 초마다 한 행을 호출하려고합니다. 절전 기능을 사용할 때마다 코드는 2 초 동안 기다린 후 다음 명령으로 진행합니다. 하지만 다른 지침을 어지럽히 지 않고 매 2 초마다 기능을 호출하고 싶습니다. 예;X 초 단위의 호출 함수

a = None 
def foo(): 
    bar() 

    a = a * 12 
    print "A : ",a 

def bar(): 
    a = 0 

2 초마다 a를 재설정해야합니다. 그러나 2 초안에 a의 값을 증가시켜 표시해야합니다. 가능한가? 어떻게?

+0

당신은 배울 필요가 있습니다 (그리고 많은 것을 배울 수 있습니다.) 스레딩. 당신의 예제에서'a'는'foo'와'bar' 사이에 * 공유되지 않습니다 *, 그들은 독립적 인 지역입니다. –

+0

@MartijnPieters 미안하다. 대답은 간단합니까? – demilg

+0

스레드 간 변수 공유 *는 복잡 할 수 있습니다. 스레딩 및 스레드 안전성을 이해해야합니다. –

답변

2

시간을 폴링 할 수 있습니다. 현재 시간을 읽고 저장하고 물건을 처리 한 다음 현재 시간이 저장된 시간 + 2 초와 일치 할 때까지 기다리는 중입니다. 당신이 원한다면 당신의 물건 뒤에 수면을 추가 할 수 있습니다. 그러나 인터벌 2 초가 지나기 전에 수면이 끝나야합니다. 예 : 1.5 초만 잘 수 있습니다.

독립적으로 실행하려면 스레딩을 사용해야합니다. http://docs.python.org/2/library/threading.html

당신은 여기에 대한 답변을 고려할 수 있습니다 : Executing periodic actions in Python

import time, threading 
def foo(): 
    print(time.ctime()) 
    threading.Timer(10, foo).start() 
2

사용 threading.Timer을. 하지만 별도의 타이머로 코드에서 막대를 실행하면 작동하지 않을 것이므로 먼저 스레드간에 변수를 사용하는 방법에 대해 생각해야합니다.

0

나는 스레드와 잠금을 사용하여 사용자의 요구에 접근 할 것입니다.

사실, 저는 제 친구 인 Pepe가 작성한 오픈 소스 ThreadPool을 좋아합니다.

#! /usr/bin/python 
# -*- coding: utf-8 -*- 
# File: a.py 

import threadPool 
import time 
import threading 

class A: 
    def __init__(self): 
     self.a = 1 
     self.alock = threading.Lock() 
     self.tp = threadPool.getInstance() 

    def bar(self): 
     self.alock.acquire() 
     self.a = 1 
     self.alock.release() 

    def foo(self): 
     self.tp.timer(self.bar, 2) 
     while True: 
      self.alock.acquire() 
      self.a = self.a * 12 
      self.alock.release() 
      print "A : ",self.a 
      time.sleep(0.1) 

a = A() 
a.foo() 

실행 : 여기

는 ThreadPool이 코드이며, 그 후, 가능한 해결책 :

#! /usr/bin/python 
# -*- coding: utf-8 -*- 
# File: threadPool.py 

import threading 
import Queue 
import time 
import sys 
import traceback 
import datetime 

Instance = None 

def getInstance(): 
    global Instance 
    if not Instance: 
     Instance = ThreadPool() 
    return Instance 


class ThreadPool: 
    def __init__(self,maxWorkers = 10): 
     self.tasks = Queue.Queue() 
     self.workers = 0 
     self.working = 0 
     self.maxWorkers = maxWorkers 
     self.allKilled = threading.Event() 
     self.countLock = threading.RLock() 
     self.timers = {} 
     self.timersLock = threading.Lock() 
     self.timersThreadLock = threading.Lock() 
     self.timersEvent = threading.Event() 
     self.allKilled.set() 

    def run(self,target,callback = None, *args, **kargs): 
     """ starts task. 
      target = callable to run with *args and **kargs arguments. 
      callback = callable executed when target ends 
         callback sould accept one parameter where target's 
         return value is passed. 
         If callback is None it's ignored. 
     """ 
     self.countLock.acquire() 
     if not self.workers: 
      self.addWorker() 
     self.countLock.release() 
     self.tasks.put((target,callback,args,kargs)) 

    def setMaxWorkers(self,num): 
     """ Sets the maximum workers to create. 
      num = max workers 
        If number passed is lower than active workers 
        it will kill workers to match that number. 
     """ 
     self.countLock.acquire() 
     self.maxWorkers = num 
     if self.workers > self.maxWorkers: 
      self.killWorker(self.workers - self.maxWorkers) 
     self.countLock.release() 

    def addWorker(self,num = 1): 
     """ Add workers. 
      num = number of workers to create/add. 
     """ 
     for x in xrange(num): 
      self.countLock.acquire() 
      self.workers += 1 
      self.allKilled.clear() 
      self.countLock.release()   
      t = threading.Thread(target = self.__workerThread) 
      t.setDaemon(True) 
      t.start() 

    def killWorker(self,num = 1): 
     """ Kill workers. 
      num = number of workers to kill. 
     """ 
     self.countLock.acquire() 
     if num > self.workers: 
      num = self.workers 
     self.countLock.release() 
     for x in xrange(num): 
      self.tasks.put("exit")    

    def killAllWorkers(self,wait = None): 
     """ Kill all active workers. 
      wait = seconds to wait until last worker ends 
        if None it waits forever. 
     """ 

     self.countLock.acquire() 
     self.killWorker(self.workers) 
     self.countLock.release() 
     self.allKilled.wait(wait) 

    def __workerThread(self): 
     while True: 
      task = self.tasks.get() 
      # exit is "special" tasks to kill thread 
      if task == "exit": 
       break 

      self.countLock.acquire() 
      self.working += 1 
      if (self.working >= self.workers) and (self.workers < self.maxWorkers): # create thread on demand 
       self.addWorker() 
      self.countLock.release() 

      fun,cb,args,kargs = task 
      try: 
       ret = fun(*args,**kargs) 
       if cb: 
        cb(ret) 
      except: 
       ty,val,tb = sys.exc_info() 
       print "Thread Catch:%s" % "".join(traceback.format_exception(ty,val,tb)) 

      self.countLock.acquire() 
      self.working -= 1 
      self.countLock.release()     
      del(fun) # Dereference all 
      del(cb) 
      del(args) 
      del(kargs) 
      del(task) 

     self.countLock.acquire() 
     self.workers -= 1 
     if not self.workers: 
      self.allKilled.set() 
     self.countLock.release() 

    def timer(self, cb, period): 
     """ Add or remove timers. 
      cb = callback function. 
      period = period in seconds (float) 
        if period is 0 timer is deleted. 
     """ 
     self.run(self.__timerThread, None, cb, period) 

    def __timerThread(self, cb, period): 
     self.timersLock.acquire() 
     self.timersEvent.set() 
     if not period: 
      if cb in self.timers: 
       del(self.timers[cb]) 
      self.timersLock.release() 
      return 

     self.timers[cb] = [period,time.time()]  
     self.timersLock.release() 

     if not self.timersThreadLock.acquire(0): 
      return 

     while True: 
      self.timersLock.acquire() 
      if len(self.timers) == 0: 
       self.timersThreadLock.release() 
       self.timersLock.release() 
       break 

      minWait = 30*24*3600 
      now = time.time() 
      for k,v in self.timers.items(): 
       period, last = v 
       wait = period - (now - last) 
       if wait <=0: 
        self.run(k) 
        wait = period 
        v[1] = now 
       if wait < minWait: 
        minWait = wait 
      self.timersLock.release() 
      self.timersEvent.wait(minWait) 
      self.timersEvent.clear()   

그리고 가능한 솔루션

$ python a.py 
관련 문제