I have a number of instances of a class, and I'd like to modify each of them by calling a method. The method will call a system command, however, that takes a while to return, so I'd like to do several in parallel. I thought this would be a very simple thing to do, but I am stumped. Here is an example that is analogous to what I want to accomplish:
import os
class SquareMe():
def __init__(self, x):
self.val = x
def square(self):
os.system('sleep 10') # I'll call a slow program
self.val = self.val **2
if __name__ == '__main__':
objs = [SquareMe(x) for x in range(4)]
for obj in objs:
obj.square() # this is where I want to parallelize it
print([obj.val for obj in objs])
This code works (it prints [0, 1, 4, 9]), but it takes 40 seconds to run. I'm trying to get that down to roughly 10 seconds.
I've looked at the subprocess and multiprocessing modules but, as I understand it, they will pickle the object before evaluating square(), meaning the copy of each object will be modified, and the originals will remain untouched. I thought the solution would be to return self and overwrite the original, but that is far from straightforward, if it is possible. I looked into threading and got the impression that I would run into the same problem there.
I also looked into using async (I'm using python 3.5). From what I can tell, system calls (including 'sleep 10') are blocking, meaning that async will not speed it up.
Is there a simple, elegant, pythonic way to do this?