读取umask(线程安全)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读取umask(线程安全)相关的知识,希望对你有一定的参考价值。
我知道这种模式在Python中读取umask:
current_umask = os.umask(0) # line1
os.umask(current_umask) # line2
return current_umask # line3
但这不是线程安全的。
在line1和line2之间执行的线程将具有不同的umask。
是否有一种线程安全的方式来读取Python中的umask?
答案
如果您的系统在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
在CentOS 7.5,Debian 9.6下测试。
或者,你可以添加一个线程锁:)
另一答案
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()))
另一答案
我所知道的唯一真正,毫不含糊的线程安全方式是调用一个新进程。
import subprocess
umask_cmd = ('python', '-c', 'import os; print(os.umask(0777))')
umask = int(subprocess.check_output(umask_cmd))
请注意,如果您有bash或其他shell,您也可以调用它。因为它可能在一个奇怪的系统上,所以我选择在umask_cmd
中使用python子进程,因为你必须有python。如果您使用的是非奇怪的* nix系统,那么您可以使用sh或bash代替。
另一答案
可以通过创建临时文件并检查其权限来确定umask。这适用于所有* nix系统:
def get_umask():
import os, os.path, random, tempfile
while True:
# Generate a random name
name = 'test'
for _ in range(8):
name += chr(random.randint(ord('a'), ord('z')))
path = os.path.join(tempfile.gettempdir(), name)
# Attempt to create a file with full permissions
try:
fd = os.open(path, os.O_RDONLY|os.O_CREAT|os.O_EXCL, 0o777)
except FileExistsError:
# File exists, try again
continue
try:
# Deduce umask from the file's permission bits
return 0o777 & ~os.stat(fd).st_mode
finally:
os.close(fd)
os.unlink(path)
以上是关于读取umask(线程安全)的主要内容,如果未能解决你的问题,请参考以下文章