Robert's earlier suggestion that a max==0 means infinite is pretty good - I'm leaning towards that now.
Given that, here's a version that is mainly aiming for clarity:

    iterations = 0 
    total_tasks_processed = 0 
    tasks_processed = True

    # Keep processing if we have processed any tasks.
    while tasks_processed > 0:

        tasks_processed = _run(taskq_service, queue_names)
        total_tasks_processed += tasks_processed
        iterations += 1

        # Exit loop if max is set and we have reached it.
        if max_iterations and iterations >= max_iterations:
            break