如何以线程安全的方式更改目录?

huangapple go评论69阅读模式
英文:

How can I change directories in a thread safe way?

问题

我想要创建两个线程,并将每个线程移动到不同的工作目录。

std::thread t1([](){
    boost::filesystem::current_path("/place/one");
    // 在"place/one"目录中操作
});

std::thread t2([](){
    boost::filesystem::current_path("/place/two");
    // 在"place/two"目录中操作
});

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

然而,这种方法不会生效。

Boost 文档显示如下:

void current_path(const path& p);

效果: 建立了后置条件,就像通过 ISO/IEC 9945 chdir() 那样。

后置条件: equivalent(p, current_path())。

抛出: 如错误报告中所指定的。

[注意: 对于许多操作系统来说,当前路径是一个危险的全局状态。它可能会被第三方或系统库函数,或者其他线程意外地更改。-- 结束注意]

由于current_pathchdir不是线程安全的,最后一个更改目录的线程会影响其他线程的全局状态。
它们将都在相同的目录中操作。

但我的替代方案是什么?基于现有的代码,我希望避免根据不同的当前工作目录重写线程逻辑。生成进程是我的唯一选择吗?

英文:

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?

答案1

得分: 1

作为UNIX进程,它有一个唯一的当前目录,所有线程共享,如果你需要不同的当前路径,那么生成一个进程确实是必需的。然而,这会降低可移植性。

英文:

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.

huangapple
  • 本文由 发表于 2020年1月3日 14:13:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/59573987.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定