flock
ロックはスレッドを気にしません。実際、ロックもプロセスを気にしません。2つのプロセス(フォークを介して継承)で同じファイル記述子を使用する場合、そのFDでファイルをロックするいずれかのプロセスは、両方のプロセスのロックを取得します。つまり、次のコードでは、両方の flock
呼び出しが成功を返します。子プロセスはファイルをロックし、親プロセスは両方とも同じFDであるため、ブロックするのではなく同じロックを取得します。
import fcntl, time, os
f = open("testfile", "w+")
print "Locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "locked"
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
if os.fork() == 0:
# We're in the child process, and we have an inherited copy of the fd.
# Lock the file.
print "Child process locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "Child process locked..."
time.sleep(1000)
else:
# We're in the parent. Give the child process a moment to lock the file.
time.sleep(0.5)
print "Parent process locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "Parent process locked"
time.sleep(1000)
同じトークンで、同じファイルを2回ロックし、ファイル記述子が異なる場合、同じプロセスにいるか同じスレッドにいるかに関係なく、ロックは互いにブロックします。flock(2)を参照してください。If a process uses open(2) (or similar) to obtain more than one descriptor for the same file, these descriptors are treated independently by flock(). An attempt to lock the file using one of these file descriptors may be denied by a lock that the calling process has already placed via another descriptor.
Linuxカーネルにとって、プロセスとスレッドは本質的に同じものであり、カーネルレベルのAPIによって一般的に同じように扱われることを覚えておくと便利です。ほとんどの場合、syscallがプロセス間の子/親の動作を文書化する場合、同じことがスレッドにも当てはまります。
もちろん、この動作を自分でテストすることはできます(おそらくそうすべきです)。