I am new to coding threads. I have 5,000,000 tasks I need to do with only 9 threads available. My current code seems to be creating more tasks than the available threads. I haven't done the calculation but it roughly means I will have ~4,999,900 tasks in the queue when only 100 tasks have been completed (you get the point). This means the memory is being used inefficiently. I could've had 81 tasks in the queue with 9 threads, and as soon as 1 task is complete, I add a new task to the queue rather than making all 5,000,000 tasks at once.
My question is, how do I make the task queue smaller (say 81 tasks) and then once a task is complete, I add a new task to the queue. Hence, maintaining an 81 task queue. Also, I append the thread threads.append(executor.submit(do_task, i)) to the threads list. That also means the threads list is going to be 5,000,000 long at the end of execution, hence, inefficient. I only append the threads so it doesn't jump the code to the printing of nums. How can I fix that too? While making sure print(f'Nums: {nums}') is only printed once all 5,000,000 tasks have been completed.
import threading
import time
from concurrent.futures import ThreadPoolExecutor
def do_task(i):
time.sleep(2)
nums.append(i)
print(f'Thread: {threading.current_thread()} | i = {i}')
executor = ThreadPoolExecutor(max_workers=9)
threads = []
nums = []
for i in range(0, 5000000):
time.sleep(0.5) # this sleep function represents me creating the task for the thread to do
print(f'About to submit {i}')
threads.append(executor.submit(do_task, i))
print(f'Thread count: {len(threads)}')
for thread in threads:
thread.result()
print(f'Nums: {nums}')