【问题标题】:thread safe function to create directory in C在 C 中创建目录的线程安全函数
【发布时间】:2017-10-11 07:37:39
【问题描述】:

我正在实现一个线程安全函数来创建目录如果它不存在

void create_directory(char *str){   
    pthread_mutex_lock(mutex);
    if (stat(str, &st) == -1) {
        mkdir(str, 0700);
    }
    pthread_mutex_unlock(mutex);
}

线程_1:

create_directory("dir1");

线程_2:

create_directory("dir1");

线程_3:

create_directory("dir2");


Thread_1 和 Thread_2 正在尝试创建相同的目录,并且代码按预期工作。问题是当 Thread_3 尝试创建另一个目录,即“dir2”,它与目录“dir1”无关,然后 Thread_3 也被阻塞了。

我想要的是锁定目录而不是锁定代码部分。我怎样才能做到这一点。

或者有没有其他方法可以实现线程安全功能来创建目录。 或者 C 中有什么函数可以做到这一点。

【问题讨论】:

  • 如果另一个进程在statmkdir之间创建目录怎么办?
  • 请注意,使用statmkdir 时会出现TOCTOU(检查时间,使用时间)问题。另请注意,stat() 可能由于 ENOENT 以外的其他原因而失败,即使名称不是目录,stat() 也可能成功。另见Creating a directory treeChecking if a directory exists
  • 你是对的,可能会出现TOCTOU问题。由于我在程序的专用目录中创建目录,因此我不希望任何其他进程创建相同的目录。而且,我的进程的所有线程都使用这个函数来创建目录。

标签: c multithreading directory


【解决方案1】:

为什么不直接创建目录,如果返回EEXIST 错误,请忽略它。最终结果是一样的:你调用你的函数,当它返回时有一个目录。

这是一个幂等操作,因此无需处理复杂的锁定方案。特别是因为它们不会阻止不同的进程创建相同的目录。

【讨论】:

    【解决方案2】:

    您可以将字符串散列为 4 位。这将为您提供 16 种可能的选择。创建一个包含 16 个互斥锁的数组,并仅在您的哈希值上获取锁。碰撞仍然可能发生,但会减少。

    您可以将哈希宽度增加到 8 位以减少冲突,但您需要更多互斥对象。

    其他方法是不对调用 mkdir 的昂贵部分获取锁(它调用系统调用)。

    但要维护当前正在创建的目录列表。每个尝试创建目录的线程首先检查该名称是否已经在列表中。如果是,它会等待。

    如果没有,则输入插入名称并开始创建目录。完成后,它会从列表中删除该名称。

    只有添加到列表和检查的部分必须用一个简单的锁来保护,并且操作会很快发生。所以在其他目录上运行的其他线程不必等待太多。

    【讨论】:

    • 好主意,但 Art 的答案可能更好。还是投了赞成票。
    【解决方案3】:

    如果您想锁定目录,只需调用mkdir 并让操作系统完成其工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      相关资源
      最近更新 更多