2015-12-09 62 views
0

後執行額外的代碼,我有以下代碼:Python的線程:監視線程和線程完成

class MyThread(Thread): 
    def __init__(self, command, template, env, build_flavor, logger): 
     Thread.__init__(self) 
     self.command = command 
     self.template = template 
     self.env = env 
     self.build_flavor = build_flavor 
     self.logger = logger 

    def run(self): 
     self.logger.info('Running (%s)...this may take several minutes. Please be patient' % self.build_flavor) 
     run_command(self.command, self.template, self.env) 
     self.logger.info('Complete (%s)' % self.build_flavor) 
     return 

然後在另一個班級,當我創建實際的線程:

if self.build_type == 'default': 
      threads = [] 
      for t in self.template: 
       modify_template(t) 
       build_flavor = self.getmatch(t) 
       thread = MyThread(packer, t, self.new_env, build_flavor, self.logger) 
       thread.setName(build_flavor) 
       thread.start() 
       threads.append(thread) 
      for thread in threads: 
       thread.join() 
      vmware_create() 
      openstack_create() 

不幸的是,在線程爲.join()'d後,我在串行調用vmware_create()和openstack_create()。我希望能夠在它們各自的線程完成後執行其中的每一個,以便在啓動其中一個* _create()函數之前,我不會等待兩個線程完成...然後等待第一個完成在執行第二個

即現在vmware_create()只會在兩個線程完成後纔會執行,一旦vmware_create()完成,只有openstack_create()纔會開始。我希望能夠等待相應的線程完成,然後爲首先完成的任何線程執行_create()函數,等待第二個線程完成,然後一旦完成,立即執行_create ()函數進行真正的並行化。

我一直無法弄清楚如何做到這一點,需要幫助。

+0

你爲什麼不從線程調用它們? – user193661

+0

@ user193661是的,這將是可取的,以下從邁克穆勒的答案似乎工作。我想我只是需要一個外部視角,因爲我不知道如何去做,但邁克似乎有一個非常好的工作解決方案。不知道爲什麼我的問題是downvoted ... – digitalsy

回答

1

功能是對象。只是他們交給線程:

class MyThread(Thread): 
    def __init__(self, command, template, env, build_flavor, logger, func=None): 
     Thread.__init__(self) 
     self.command = command 
     self.template = template 
     self.env = env 
     self.build_flavor = build_flavor 
     self.logger = logger 
     self.func = func 

    def run(self): 
     self.logger.info('Running (%s)...this may take several minutes. Please be patient' % self.build_flavor) 
     run_command(self.command, self.template, self.env) 
     self.logger.info('Complete (%s)' % self.build_flavor) 
     # call func if it is there 
     if self.func: 
      self.func() 
     return 

現在,我公司供應的第一兩個線程與函數調用:

if self.build_type == 'default': 
    threads = [] 
    funcs = {0: vmware_create, 1: openstack_create} 
    for i, t in enumerate(self.template): 
     modify_template(t) 
     build_flavor = self.getmatch(t) 
     func = funcs.get(i, None) 
     thread = MyThread(packer, t, self.new_env, build_flavor, 
          self.logger, func=func) 
     thread.setName(build_flavor) 
     thread.start() 
     threads.append(thread) 
    for thread in threads: 
     thread.join() 

當然,你可以將它們添加到任何其他線程。

+0

這正是我正在尋找。謝謝!我無法弄清楚如何根據正在執行的線程來調用適當的函數,但這似乎確實起作用。乾杯! – digitalsy

+0

很高興聽到它的幫助。你可以[接受](http://stackoverflow.com/help/accepted-answer)一個答案,如果它解決了你的問題。 –

+0

完成,再次感謝邁克 – digitalsy