3

I'd like to spawn 2 threads and move each one into a different working directory.

std::thread t1([](){
    boost::filesystem::current_path("/place/one");
    // operate within "place/one"
});

std::thread t2([](){
    boost::filesystem::current_path("/place/two");
    // operate within "place/two"
});

t1.join();
t2.join();

However, this will not work.

Boost documentation shows the following:

void current_path(const path& p);

Effects: Establishes the postcondition, as if by ISO/IEC 9945 chdir().

Postcondition: equivalent(p, current_path()).

Throws: As specified in Error reporting.

[Note: The current path for many operating systems is a dangerous global state. It may be changed unexpectedly by a third-party or system library functions, or by another thread. -- end note]

Since current_path i.e. chdir are not thread safe, the last thread to change directories will affect the global state of the other thread.
They will both operate in the same directories.

But what is my alternative? Based on the existing code, I'm hoping to avoid rewiring thread logic on the assumption of a different current working directory. Are spawning processes my only other option?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • work around the working directory being a program-wide state rather than a thread-specific one. Not sure if thread can somehow me augmented to have its own cwd. – Trevor Hickey Jan 03 '20 at 06:20
  • 1
    All threads in a process share the same work dir. You can't change that. So you need one of your proposed alternatives. – Mat Jan 03 '20 at 06:20
  • 1
    For what specifically do you need to set the working directory that wouldn't work using an absolute path? – walnut Jan 03 '20 at 06:21
  • @walnut a significant amount of code would need to be rewritten. I agree that absolute paths would be ideal, but hoping to resolve from outside that code. – Trevor Hickey Jan 03 '20 at 06:25
  • 3
    @TrevorHickey you don't have a choice in this situation. You have to rewrite the code to stop relying on any CWD at all. That means using absolute path strings instead. Bite the bullet and just do it. Your code will be better and safer for it. – Remy Lebeau Jan 03 '20 at 06:28
  • Depending on what your threads do, you can explore the [`fork`](http://man7.org/linux/man-pages/man2/fork.2.html) solution. As you end up with two processes, you can have different current_path. But I would bet that refactoring using relative paths from a single location in your code is what you want. – Meatboy 106 Jan 03 '20 at 09:29

1 Answers1

1

As a UNIX process has a unique current directory shared by all its threads, spawning a process is indeed a requirement if you need different current_path. However, portability will suffer from it.

Meatboy 106
  • 196
  • 7