def generate2(func, args_gen, kw_gen=None, ntasks=None, ordered=True,
              force_serial=False, use_pool=False, chunksize=None, nprocs=None,
              progkw={}, nTasks=None, verbose=None):
    r
    if verbose is None:
        verbose = 2
    if ntasks is None:
        ntasks = nTasks
    if ntasks is None:
        try:
            ntasks = len(args_gen)
        except TypeError:
            args_gen = list(args_gen)
            ntasks = len(args_gen)
    if ntasks == 1 or ntasks < __MIN_PARALLEL_TASKS__:
        force_serial = True
    if __FORCE_SERIAL__:
        force_serial = __FORCE_SERIAL__
    if ntasks == 0:
        if verbose:
            print('[ut.generate2] submitted 0 tasks')
        raise StopIteration
    if nprocs is None:
        nprocs = min(ntasks, get_default_numprocs())
    if nprocs == 1:
        force_serial = True
    if kw_gen is None:
        kw_gen = [{}] * ntasks
    if isinstance(kw_gen, dict):
        kw_gen = [kw_gen] * ntasks
    if force_serial:
        for result in _generate_serial2(func, args_gen, kw_gen,
                                        ntasks=ntasks, progkw=progkw,
                                        verbose=verbose):
            yield result
    else:
        if verbose:
            gentype = 'mp' if use_pool else 'futures'
            fmtstr = '[generate2] executing {} {} tasks using {} {} procs'
            print(fmtstr.format(ntasks, get_funcname(func), nprocs, gentype))
        if verbose > 1:
            lbl = '(pargen) %s: ' % (get_funcname(func),)
            progkw_ = dict(freq=None, bs=True, adjust=False, freq_est='absolute')
            progkw_.update(progkw)
            progpart = util_progress.ProgPartial(length=ntasks, lbl=lbl, **progkw_)
        if use_pool:
            if chunksize is None:
                chunksize = max(min(4, ntasks), min(8, ntasks // (nprocs ** 2)))
            try:
                pool = multiprocessing.Pool(nprocs)
                if ordered:
                    pmap_func = pool.imap
                else:
                    pmap_func = pool.imap_unordered
                wrapped_arg_gen = zip([func] * len(args_gen), args_gen, kw_gen)
                res_gen = pmap_func(_kw_wrap_worker, wrapped_arg_gen,
                                    chunksize)
                if verbose > 1:
                    res_gen = progpart(res_gen)
                for res in res_gen:
                    yield res
            finally:
                pool.close()
                pool.join()
        else:
            executor = futures.ProcessPoolExecutor(nprocs)
            try:
                fs_list = [executor.submit(func, *a, **k)
                           for a, k in zip(args_gen, kw_gen)]
                fs_gen = fs_list
                if not ordered:
                    fs_gen = futures.as_completed(fs_gen)
                if verbose > 1:
                    fs_gen = progpart(fs_gen)
                for fs in fs_gen:
                    yield fs.result()
            finally:
                executor.shutdown(wait=True)