【问题标题】:Too many open files even with O_EXCL即使使用 O_EXCL,打开的文件也太多
【发布时间】:2020-02-20 06:09:35
【问题描述】:

我正在尝试编写一个函数,该函数能够确定调用它的进程是否是第一个调用它的进程,而无需使用任何锁。

这是我当前的实现。

def is_first_process(path):
    filename = os.path.join(path, "first.file")
    try:
        fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
        os.close(fd)
        return True
    except FileExistsError:
        return False

我这样测试上面的函数:

def test_is_first_process():
    path = "/tmp/first_process"
    shutil.rmtree(path, ignore_errors=True)
    process_list = []

    def helper(fn, arg, shared_list):
        shared_list.append(fn(arg))

    for _ in range(1000):
        makedirs(path)
        manager = Manager()
        results = manager.list()
        for i in range(1000):
            p = Process(target=helper, args=(is_first_process, path, results))
            p.start()
            process_list.append(p)

        for p in process_list:
            p.join()

        assert results.count(True) == 1
        shutil.rmtree(path, ignore_errors=True)

对于较大的 m*n,测试错误会出现以下错误:

E OSError: [Errno 24] Too many open files

但不适用于较小的值 (m*n

我对 os.O_EXCL 标志的理解是,如果 FileExistsError 已经存在,它会引发它。

我对这个标志的理解不正确吗? 如何正确实现和测试可以确定写入目录的第一个进程的函数?

【问题讨论】:

    标签: python


    【解决方案1】:

    我认为您可能误解了您所看到的错误。关于Too many open files 的错误消息意味着它所说的,您同时打开了太多文件。您的一个文件不一定一次被打开多次。

    处理进程间通信的多处理代码可能会导致您尝试同时启动的 1000 个独立进程出现问题。那是很多过程!

    许多操作系统限制每个进程可以打开多少文件,并且通常还限制每个登录用户,因此即使在大量进程中的每个进程中只打开几个文件也可能是个问题。您可能可以使用ulimit -n 或类似的配置程序修改系统上的限制。

    但真正的问题是,为什么您认为需要一次测试 1000 个进程?即使在大型系统上,您也可能不会拥有那么多 CPU 内核,因此这些进程中的大多数必然会处于休眠状态,而只有少数进程在运行。我建议您使用最多是系统内核数量的小倍数(例如 2 倍)的进程进行测试,再多的进程只会浪费您的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多