0

What my code does is generate an X amount of random lines, each is the length of X

My program is almost finished but I couldn't get the time to work, more specifically, get it out of the function, I know it calculates the time correctly because if I put a print in the break section it actually prints the time, but when I want to use it outside the function it never is defined

I tried tons of stuff, like globalizing it in the function, outside function (it doesn't change from 0, which means the function is not changing the variable for some reason) , tried float, tried adding the line elapsed = MainCode() , but all never working, I spent like 6 hours with this single issue, 3 of those hours with other programmers from Python's official discord server for extra help, all were also confused as to why is it still not considered defined

here's my full code, any help is appreciated

import random
import string
import multiprocessing
import os
import sys
import time

if __name__ == "__main__":
    lines_wanted = input("input how many lines: ") #user can input how many lines he wants
    length = input("How long: ") #user can enter how long each line should be

def MainCode(lines_wanted, length):
    global elapsed
    elapsed = 0.0
    starttime = time.time() # start the time
    file = open("blablabla.txt", "a",) # open/create the file
    i = 0
    while 1 == 1:
        file.write(''.join(random.choice(string.ascii_letters + string.digits + ".") for i in range(int(length))) + "\n") # write the randomly generated lowercase string
        i += 1 * multiprocessing.cpu_count() # count how many lines the loop is on
        if i >= int(lines_wanted): # If it reaches the lines it would stop writing
            endtime = time.time() # stop the time
            elapsed = endtime - starttime #calculate the time
            return elapsed
            break

processes = []
if __name__ == '__main__':
    for _ in range(multiprocessing.cpu_count()):
        p = multiprocessing.Process(target=MainCode, args=(lines_wanted, length))
        p.start()
        processes.append(p)

    for process in processes:
        process.join()

elapsee = MainCode()

if __name__ == "__main__": # Prints this after finshing the func above
    print(f"Finished Writting {lines_wanted} lines, took {elapsee:.1f} to generate")
2
  • 1
    1 == 1 is an arbitrary way of writing True. Commented Jun 7, 2020 at 22:25
  • I was actually looking for something like this, thanks Commented Jun 7, 2020 at 22:29

2 Answers 2

1

elapsed is only written by MainCode, which is only called in subprocesses started by multiprocessing.Process. Being in a different process, your main program has no opportunity to observe those variables; unlike threads, subprocesses do not share your namespace. As such, you want to communicate the value somehow. This is conveniently handled by multiprocessing.Pool:

#! /usr/bin/env python3

import multiprocessing
import os
import time

def worker(arg):
    starttime = time.time()
    time.sleep(3)
    endtime = time.time()
    return endtime - starttime

if __name__ == '__main__':
    wallstart = time.time()
    with multiprocessing.Pool() as pool:
        times = pool.map(worker, [3]*os.cpu_count())
    wallstop = time.time()
    print(f'Wall time: {wallstop-wallstart}, worker time: {sum(times)}')

Example run result:

$ python3 multiprocess.py
Wall time: 4.356384515762329, worker time: 24.002115488052368

Of course, the typos others pointed out would keep you from finding the intended variable as well.

One way to know this wouldn't do what you intended is the fact that __name__ must differ between the subprocess and main program. That means it's in a different module, even if they were sharing a process, so they don't share a global namespace.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, its in different module to prevent them from printing it a lot of times (each core prints it), thanks for the detailed answer
0

First, you're trying to print "elapsee" instead of "elapsed".

Second, you probably want to put all the time code outside MainCode completely, instead starting before the process start and the joins, if you want an accurate total elapsed time.

2 Comments

I wrote elapsee as I was trying elapsee = MainCode() with the return, one of the many ideas I tried
I've made it into a function so I can multiprocessor it, I thought this how it worked, anyways, I've only put it inside the loop so It only counts the time elapsed while generating the file, not when you actually start the program from the beginning

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.