Here is a simple code snippet that should fit the requirements:
import multiprocessing
import time
POOL_SIZE = 4
STEP = 1
def sleep(seconds: int):
time.sleep(seconds)
def main():
tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pool = [None] * POOL_SIZE
while tasks or [item for item in pool if item is not None]:
for i in range(len(pool)):
if pool[i] is not None and not pool[i].is_alive():
# Finished task. Clear the resource.
pool[i] = None
if pool[i] is None:
# Free resource. Start new task if any are left.
if tasks:
task = tasks.pop(0)
pool[i] = multiprocessing.Process(target=sleep, args=(task,))
pool[i].start()
time.sleep(STEP)
if __name__ == '__main__':
main()
The manager has a tasks
list of arbitrary length, here are tasks for simplicity represented by integers that are being placed as arguments to a sleep
function. It also has a pool
list, initially empty, representing the available resource.
The manager periodically visits all currently running processes and checks if they are finished or not. It also starts new processes if the resource becomes available. The whole cycle is being repeated until there are no tasks and no currently running processes left. The STEP
value is here to save the computing power - you generally don't need to check the running processes every millisecond.
As for the caveats, there are some guidelines that should be kept in mind when using multiprocessing.