9

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.

Ken T
  • 2,255
  • 1
  • 23
  • 30

1 Answers1

9

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.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
jorgenkg
  • 4,140
  • 1
  • 34
  • 48
  • 1
    See my updated information, the working directory will change for all threads once you use os.chdir() to change the working directory. But I want each thread has its own working directory. – Ken T Aug 30 '13 at 02:49
  • That's correct! But it is impossible to define a general working directory, that isn't general! The process owns the workingdir variable, but a thread may create its own workingdir if it calls `os.chdir`. If I've understood you correctly, what you hope for is impossible. – jorgenkg Aug 30 '13 at 05:56
  • A hack that may help you, is just to feed your `Thread class` a path variable. – jorgenkg Aug 30 '13 at 05:59
  • I am newbie in writing class. How to input a path into the inipath? – Ken T Aug 31 '13 at 08:45
  • That is very easy, take a look at the 13th line in the updated code above! – jorgenkg Sep 01 '13 at 08:02
  • I don't understand. @jorgenkg how is this an answer to the thread question on the thread question of how to specify a thread's cwd ? It is possible to apply a lock on a os.chdir cmd. – Peter Moore Oct 24 '21 at 15:23