Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify a local working directory for threading.Thread and multiprocessing.Pool?

Just like subprocess.Popen( target=, cwd=), it can specify its own local working directory. I dont want to specify the absolute path every time because simple is better than complex. os.chdir() doesn't work at all since it sets a global variable (right?). Whenever there are multiple threads, os.chdir() will fail. Any suggestions? Thank you!

I just try jorgenkg's code and modify a little bit and you may see why I have to ask this question. Here is the code.

import os
import threading
import time

class child(threading.Thread):
    def run(self ):
        for i in range(1,3):
            print "I am " + str(threading.current_thread())[7:15] + " in " + os.getcwd() + '\r\n'
            time.sleep(2)            


child().start() # prints "/username/path"


os.chdir('C://') # The process is changing directory
child().start() # prints "/"

Here is the Result.

I am Thread-1 in C:\Python27\Projects

I am Thread-2 in C:\



I am Thread-1 in C:\

I am Thread-2 in C:\

You can see that Thread-2 is no long working on its original working directory after os.chdir() is invoked.

like image 313
Ken T Avatar asked Aug 29 '13 16:08

Ken T


1 Answers

As you state, the current directory path belongs to the process that owns the threads.

Before you create your threads, you will have to set the path before initializing the child threads that will share os.getcwd(). Here's a simple code example:

import os
import threading
import time

class child(threading.Thread):
    def __init__(self, initpath=None):
        # initpath could be a string fed to many initializations

        time.sleep(0.05) # print() doesn't seem thread safe, this delays it.

        super(child, self).__init__()

        if initpath is not None:
            os.chdir(initpath)

    def run(self):
        print(os.getcwd())
        time.sleep(2)
        print("slept "+os.getcwd())  # These will all show the last path.

child().start() # Prints your initial path.

# Both print "/home/username/path/somefolder/".
child(initpath="/home/username/path/somefolder/").start() 
child().start()

os.chdir("/") # The process is changing directory
child().start() # prints "/"

As above, once the directory is changed, all threads change with it. Hence, you cannot use os.chdir() concurrently across multiple threads.

like image 104
jorgenkg Avatar answered Sep 18 '22 02:09

jorgenkg