Gamblers ruin, parallel compute trials
Assigning number of processors

You currently set procs = 3, specifically for your 4-core machine. You can get the number of (logical) cores of your machine using the multiprocessing.cpu_count function:

from multiprocessing import Pool, cpu_count
procs = cpu_count() - 1


Create Pool just once

Rather than creating a new Pool every iteration of your for-loop, it is better to just create it once and keep using the same one. By using the with statement, it also makes sure to close it all neatly when you're done with it.

with Pool(procs) as p:
    for max_iter in max_iter_list:
        jobs = [max_iter] * n_trials
        duration_list = p.map(simulate_game, jobs)
        gambler_stats.update_stats(duration_list)


Hardcoded values in simulate_games function

First of all, you can define your default values in the function definition. This also makes the difference more clear between the hardcoded defaults and initializations like cur_iter = 0

def simulate_game(max_iter, 
                  gambler_limit=100, 
                  house_limit=200, 
                  gambler_win_prob=0.5):


Create different fixed-value alternative using partial

To have a fixed different set of default values, you could use functools.partial:

from functools import partial
simulate_high_roller = partial(simulate_game, gambler_limit=1_000)
with Pool(procs) as p:
    duration_list = p.map(simulate_high_roller , jobs)


Mapping with multiple arguments: starmap

If instead you want to simulate using a whole range of parameter values, Pool.starmap is probably what you're looking for. Just like the 'regular' itertools.starmap, it allows you to pass in a list of tuples that it will unpack and pass to your function.

So if you have pre-defined lists of parameters you want to simulate, you can use zip to create the tuples.

# Example
max_iter_list = [10, 20, 50]
gambler_limits = [50, 100, 200]
house_limits = [150, 200, 250]
win_probabilities = [0.6, 0.5, 0.4]

with Pool(procs) as p:
    for arguments in zip(max_iter_list, gambler_limits, house_limits, win_probabilities):
        jobs = [arguments] * n_trials
        duration_list = p.starmap(simulate_game, jobs)


In case of a full grid-search of your parameters, this combines nicely with itertools.product, although that set of combinations will grow quite fast, so be deliberate about which ones you need to test.

&gt;&gt;&gt; from itertools import product
&gt;&gt;&gt; arguments = list(product(max_iter_list, gambler_limits, 
...                          house_limits, win_probabilities))
&gt;&gt;&gt; print(arguments)
[(10, 50, 150, 0.6),
 (10, 50, 150, 0.5),
 (10, 50, 150, 0.4),
 (10, 50, 200, 0.6),
 ...
 (50, 200, 200, 0.4),
 (50, 200, 250, 0.6),
 (50, 200, 250, 0.5),
 (50, 200, 250, 0.4)]
&gt;&gt;&gt; len(arguments)
81