读取umask(线程安全)

gue*_*tli 13 python umask thread-safety

我知道这种模式在Python中读取umask:

current_umask = os.umask(0)  # line1
os.umask(current_umask)      # line2
return current_umask         # line3
Run Code Online (Sandbox Code Playgroud)

但这不是线程安全的.

在line1和line2之间执行的线程将具有不同的umask.

是否有一种线程安全的方式来读取Python中的umask?

相关:https://bugs.python.org/issue35275

geo*_*xsh 10

如果你的系统有Umask字段/proc/[pid]/status,你可以从上面读取:

import os

def getumask():
    pid = os.getpid()
    with open(f'/proc/{pid}/status') as f:
        for l in f:
            if l.startswith('Umask'):
                return int(l.split()[1], base=8)
        return None
Run Code Online (Sandbox Code Playgroud)

在CentOS 7.5,Debian 9.6下测试.

或者,你可以添加一个线程锁:)

  • 而不是使用`os.getpid()`和插值,你可以从`/ proc/self/status`读取. (3认同)

VPf*_*PfB 5

umask由子进程继承.您可以创建一个管道,分叉一个子进程,在那里获取umask并将结果写入管道,以便父级可以读取它.

相当昂贵,但没有任何特殊要求,如/proc虚拟文件系统.只有低级别OS调用(所有异步安全)并且下面没有错误检查的示例:

import os
import struct

def get_umask():
    pipe = os.pipe()
    pid = os.fork()
    if pid == 0:
        os.close(pipe[0])
        umask = os.umask(0)
        os.write(pipe[1], struct.pack('H', umask))
        os.close(pipe[1])
        os._exit(0)
    else:
        os.close(pipe[1])
        value = os.read(pipe[0], 2)
        os.close(pipe[0])
        os.waitpid(pid, 0)
        return struct.unpack('H', value)[0]

print("umask {:03o}".format(get_umask()))
Run Code Online (Sandbox Code Playgroud)