0

I am currently trying to get into Python. To explain the code below, you can see a program to compare two strategies in Roulette with many runs.

  1. The color doubling strategy without knowing what hits were before the start.
  2. The color doubling strategy with knowing that red got hit 10 times before, so I start with start value times 2^10

The "Player" class inherits both strategies. The global "globalBal_1" and "globalBal_2" variables count the profit for each strategy.

But the algorithm shall not be the problem. The main problem is that when I run the calculating function "run" with a normal call, it delivers me results. The multiprocessing processes for some reason do not change the global "globalBal_1" and "globalBal_2" variables and thus don't deliver results. Rather they do have value "0" as I have declared them initially. What am I doing wrong there? I'm fairly new into multiprocessing and Python itself.

Edit: Expected values for "globalBal_1" and"globalBal_2" are about half of "rounds", so in this case should be "500.000" (per process it is 500.000 / amount of processes). But the actual results for the multiprocessing runs are "0".

Code:

from numpy.random import randint
import time
from multiprocessing import Process

threads = 4
rounds = int(1000000 / threads)
globalBal_1 = 0
globalBal_2 = 0


class Player:
    def __init__(self):
        self.balance_1 = 0
        self.balance_2 = 0

    def strat_1(self, sequence):
        counter = 0

        for i in range(len(sequence) - 1):
            if sequence[i]:
                counter += 1
        self.balance_1 += counter

    def strat_2(self, sequence):

        for i in range(len(sequence) - 1 - 1):
            if sequence[i] == 1:
                return
        if sequence[len(sequence) - 1]:
            self.balance_2 += 2 ** (len(sequence) - 0)

    def getBal_1(self):
        return self.balance_1

    def getBal_2(self):
        return self.balance_2


def run(count):
    p1 = Player()
    print("Inside run func")
    global globalBal_1, globalBal_2

    for i in range(count):
        rolls = randint(0, 2, 10)
        p1.strat_1(rolls)
        p1.strat_2(rolls)

    globalBal_1 += p1.getBal_1()
    globalBal_2 += p1.getBal_2()
    print("Finished run func")


if __name__ == '__main__':
    start = time.time()

    procs = [Process(target=run, args=(rounds,)) for t in range(threads)]

    for p in procs:
        p.start()

    for p in procs:
        p.join()

    tempEnd = time.time()
    print("Multiprocessing result:")
    print(globalBal_1, globalBal_2, tempEnd - start)

    print("\nSingle process:")
    run(rounds)
    end = time.time()

    print(globalBal_1, globalBal_2, end - start)

Solution thanks to @mirmo and @Bing Wang:

def runMulti(count, result1, result2):
    p1 = Player()

    for i in range(count):
        rolls = randint(0, 2, 10)
        p1.strat_1(rolls)
        p1.strat_2(rolls)

    result1.value += p1.getBal_1()
    result2.value += p1.getBal_2()

    [...]

    profit1 = Value('i', 0)
    profit2 = Value('i', 0)

    procs = [Process(target=runMulti, args=(rounds, profit1, profit2)) for t in range(threads)]
  • Please include the actual and expected output, per [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (MRE). – Prune Apr 30 '21 at 23:26
  • Do you understand the difference between multi-threading vs multi-processing? If you are staying on multiprocessing read this https://stackoverflow.com/questions/17377426/shared-variable-in-pythons-multiprocessing – Bing Wang Apr 30 '21 at 23:30
  • Try to use `from multiprocessing import Process, Value, Array` – vks Apr 30 '21 at 23:31
  • Thanks @Prune for the heads up. I have updated the post. – Just_Relax May 01 '21 at 07:27
  • @BingWang I am getting there, but the link already really helps! – Just_Relax May 01 '21 at 07:27
  • @vks what exactly is your strategy there? – Just_Relax May 01 '21 at 07:27
  • @Just_Relax global variables wont work due to diff memory space. But you can use manager object and variables....basically multiprocess safe variables – vks May 01 '21 at 08:00

1 Answers1

0

Please always include the actual and expected output.

The global variables are not updated simply because there are now 4 separate processes created (hence the name multiprocessing) which have no access to the global variables you have created, or more specifically, do not have access to the global variables of the parent process.

Either return the value for each process and add them up at the end, create a queue or as mentioned use a shared object.

mirmo
  • 376
  • 3
  • 9
  • 1
    Thank you very much! This is a fact I didn't know at all, and obviously didn't think of testing. I will be working on this and will let you know! – Just_Relax May 01 '21 at 07:28