from multiprocessing import Process class A(): def __init__(self): self.my_dict = {"day": "Tuesday"} class B(): def __init__(self): self.a = A() self.__process = None def start(self): self.__process = Process(target=self.__run_process) self.__process.start() def __run_process(self): print self.a.my_dict if __name__ == "__main__": b = B() b.start() $ python test.py {'day': 'Tuesday'}
But when that process has to handle a Paramiko object where the connection has been initialized before, will not work.
import paramiko from multiprocessing import Process class B(): def __init__(self): self.__process = None self.__ssh = paramiko.SSHClient() self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.__ssh.connect('127.0.0.1', username='javi', password='xxxxxx') def start(self): self.__process = Process(target=self.__run_process) self.__process.start() def __run_process(self): try: _, stdout, _ = self.__ssh.exec_command("hostname") except: print "Failed the execution" else: print stdout.read() if __name__ == "__main__": b = B() b.start() $ python test.py Failed the execution
If you take a look at the output generated by the execution without catching it through an exception, you could observe an error as follows.
$ python test.py Process Process-1: Traceback (most recent call last): ... raise AssertionError("PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()") AssertionError: PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()
This is a well-known issue in Paramiko that has been apparently fixed in recent versions (for my tests, I am using the version provided by Ubuntu 12.10 by default: 1.7.7.1-3). A possible workaround will be for example to open a new SSH connection for that process. Let's grab an example.
import paramiko from multiprocessing import Process class B(): def __init__(self): self.__process = None self.__ssh = paramiko.SSHClient() self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) def start(self): self.__process = Process(target=self.__run_process) self.__process.start() def __run_process(self): self.__ssh.connect('127.0.0.1', username='javi', password='xxxxxx') try: _, stdout, _ = self.__ssh.exec_command("hostname") except: print "Failed the execution" else: print stdout.read() if __name__ == "__main__": b = B() b.start() $ python test.py javi-pc
As you can see above, the definition of the Paramiko object takes place within the constructor of the class B, but the connection is eventually initialized by the forked process.
No comments:
Post a Comment