1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- #! /usr/bin/env python
- # the Task class attribute "maxjobs" was deprecated in Waf 1.6
- # limiting the amount of jobs is commonly done by adding sequential
- # barriers (build groups) or even locks. But the feature might be
- # necessary in very few corner cases
- # in the following examples, remember that the method run() is the only
- # one actually executed by threads
- def configure(conf):
- pass
- def build(bld):
- bld.jobs = 4
- bld(source='foo.a bar.a truc.a')
- import threading, time
- from waflib.TaskGen import extension
- from waflib import Task
- @extension('.a')
- def process_a_files(self, node):
- self.create_task('a_to_b', node, node.change_ext('b'))
- self.create_task('b_to_c', node.change_ext('b'), node.change_ext('c'))
- class a_to_b(Task.Task):
- # classical way, using a lock or a semaphore
- # in this case, at most 2 tasks can execute at a time
- # this may lead to build starvation, as may tasks can get stalled while processing
- lock = threading.Semaphore(2)
- def run(self):
- try:
- self.lock.acquire()
- for i in range(5):
- print('a to b %r' % id(self))
- time.sleep(1)
- self.outputs[0].write('done')
- finally:
- self.lock.release()
- class b_to_c(Task.Task):
- # this will enable other tasks to run concurrently, and without additional locks
- active = []
- def runnable_status(self):
- ret = Task.Task.runnable_status(self)
- if ret == Task.RUN_ME:
- self.active = [tsk for tsk in self.active if not tsk.hasrun]
- if len(self.active) < 2:
- self.active.append(self)
- else:
- # too many tasks are still active, wait
- ret = Task.ASK_LATER
- return ret
- def run(self):
- for i in range(5):
- print('b to c %r' % id(self))
- time.sleep(1)
- self.outputs[0].write('done')
|