I believe this does what you want without any polling required, and it will only wait up to your specified DURATION.
time_waited = 0
then = time.time()
for p in processes:
if time_waited >= DURATION:
p.join(0)
p.terminate()
p.join(DURATION - time_waited)
time_waited = time.time() - then