472,805 Members | 1,020 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,805 software developers and data experts.

How to lock files (the easiest/best way)?

Is there something better than using fnctl? It seems a bit intimidating
with a quick look.
Jul 15 '06 #1
12 5370
On Sat, 15 Jul 2006 23:28:21 +0200, Sybren Stuvel wrote:
Elmo Mäntynen enlightened us with:
>Is there something better than using fnctl? It seems a bit
intimidating with a quick look.

Locking files is a complex business. What do you want to lock? Why?
Lock it with respect to what? It's easier to lock a file for local
use, compared to when the file also has to be locked from, say, use
via the network.

Sybren
Only locally. I want to be able to read/write to a single file from
multiple possibly parallel processes. Would 'touch lock' (or something
like that) work reliably (this just occured to me)?
Jul 15 '06 #2
On Sat, 15 Jul 2006 23:52:10 +0200, Sybren Stuvel wrote:
Elmo Mäntynen enlightened us with:
>Only locally. I want to be able to read/write to a single file from
multiple possibly parallel processes. Would 'touch lock' (or
something like that) work reliably (this just occured to me)?

I use a lock directory for that, os.mkdir('/var/lock/somedir').
If you use a file, you need two steps:
1) Check whether the lock-file exists
2) Create the lock-file

This is not atomic. With a directory, creating it will fail if it
already exists. This means you can atomically check for the lock, and
if it doesn't exist already, you've immediately created it too.

Sybren
Thanks. Is that what atomic basically means?
Jul 15 '06 #3
On 2006-07-15 18:52:10, Sybren Stuvel wrote:
Elmo Mäntynen enlightened us with:
>Only locally. I want to be able to read/write to a single file from
multiple possibly parallel processes. Would 'touch lock' (or
something like that) work reliably (this just occured to me)?

I use a lock directory for that, os.mkdir('/var/lock/somedir').
If you use a file, you need two steps:
1) Check whether the lock-file exists
2) Create the lock-file
cvsnt for example used to use lock files. Now it uses a lock server: a
server app that just sits there and allows different processes to acquire,
check for and release locks on files. More implementation work, probably,
but more efficient.

Gerhard

Jul 15 '06 #4
Sybren Stuvel <sy*******@YOURthirdtower.com.imaginationwrites:
I use a lock directory for that, os.mkdir('/var/lock/somedir').
If you use a file, you need two steps:
1) Check whether the lock-file exists
2) Create the lock-file
This is not atomic. With a directory, creating it will fail if it
already exists. This means you can atomically check for the lock, and
if it doesn't exist already, you've immediately created it too.
The classic way in Unix was to make a link:

1) link('some_other_file', 'lockfile')

This was atomic and would fail if lockfile already existed.

I'm not sure whether it can still be reliable, in current environments
that can involve remote file systems etc. But I'm not sure if the
mkdir approach works either.

Maybe you want to use something like shm or posh?
Jul 16 '06 #5
Elmo Mäntynen wrote:
Is there something better than using fnctl? It seems a bit intimidating
with a quick look.
try the portlocker wrapper from the active state cookbook. I have a
version which has been slightly updated for more modern pythons. I
really need to make my darcs repository visible so you could get it.

Alternatively, you can try the makedir trick. Creating directories are
atomic operations if it exists, you will get error message. If it
doesn't, you will get a directory and thereby capture the lock. You
delete the directory when you release the lock.

crude but effective. I used it in building a file based queue system.
You know, I really should learn how to build eggs because I have a whole
bunch of little pieces of software that would probably be useful to others.

---eric

Jul 16 '06 #6
In article <ma***************************************@python. org>,
Eric S. Johansson <es*@harvee.orgwrote:
>Elmo Mäntynen wrote:
>Is there something better than using fnctl? It seems a bit intimidating
with a quick look.

try the portlocker wrapper from the active state cookbook. I have a
version which has been slightly updated for more modern pythons. I
really need to make my darcs repository visible so you could get it.

Alternatively, you can try the makedir trick. Creating directories are
atomic operations if it exists, you will get error message. If it
doesn't, you will get a directory and thereby capture the lock. You
delete the directory when you release the lock.

crude but effective. I used it in building a file based queue system.
You know, I really should learn how to build eggs because I have a whole
bunch of little pieces of software that would probably be useful to others.
Here's a more complete file locking scheme which uses a lockfile with
the O_CREAT and O_EXCL flags to make the creation atomic. If it gets
the lock, it writes its PID in readable form in the file. It also does
two other things:

If you know that no process should lock the file for more than a fixed
period of time, it will retry once/second as long as the lock file is
not older than that fixed period of time. If it is older, it will
report the problem, including the PID of the locking process and exit.

This caters for a process which has set the lock file and then
terminates without removing it (which can happen do to an application
or server crash).

------------------------------------------

import os
import errno
import sys
import time
import stat

# the maximum reasonable time for aprocesstobe
max_wait = 10

lockfile = "/tmp/mylock"

while True:
try:
fd = os.open(lockfile, os.O_EXCL | os.O_RDWR | os.O_CREAT)
# we created the lockfile, so we're the owner
break
except OSError, e:
if e.errno != errno.EEXIST:
# should not occur
raise

try:
# the lock file exists, try to stat it to get its age
# and read it's contents to report the owner PID
f = open(lockfile, "r")
s = os.stat(lockfile)
except OSError, e:
if e.errno != errno.EEXIST:
sys.exit("%s exists but stat() failed: %s" %
(lockfile, e.strerror))
# we didn't create the lockfile, so it did exist, but it's
# gone now. Just try again
continue

# we didn't create the lockfile and it's still there, check
# its age
now = int(time.time())
if now - s[stat.ST_MTIME] max_wait:
pid = f.readline()
sys.exit("%s has been locked for more than " \
"%d seconds (PID %s)" % (lockfile, max_wait,
pid))

# it's not been locked too long, wait a while and retry
f.close()
time.sleep(1)

# if we get here. we have the lockfile. Convert the os.open file
# descriptor into a Python file object and record our PID in it

f = os.fdopen(fd, "w")
f.write("%d\n" % os.getpid())
f.close()


--
Jim Segrave (je*@jes-2.demon.nl)

Jul 16 '06 #7
In article <12*************@corp.supernews.com>,
Jim Segrave <je*@jes-2.demon.nlwrote:
except OSError, e:
if e.errno != errno.EEXIST:
this should read:
if e.errno != errno.ENOENT:

(it was left with EEXIST from testing this code by forcing an error,
as the code for this failure requires a very tight race condition to test)
sys.exit("%s exists but stat() failed: %s" %
(lockfile, e.strerror))
# we didn't create the lockfile, so it did exist, but it's

--
Jim Segrave (je*@jes-2.demon.nl)

Jul 16 '06 #8
In article <pa****************************@jippii.fi>,
Elmo Mäntynen <el****@jippii.fiwrote:
On Sat, 15 Jul 2006 23:52:10 +0200, Sybren Stuvel wrote:
Elmo Mäntynen enlightened us with:
Only locally. I want to be able to read/write to a single file from
multiple possibly parallel processes. Would 'touch lock' (or
something like that) work reliably (this just occured to me)?
I use a lock directory for that, os.mkdir('/var/lock/somedir').
If you use a file, you need two steps:
1) Check whether the lock-file exists
2) Create the lock-file

This is not atomic. With a directory, creating it will fail if it
already exists. This means you can atomically check for the lock, and
if it doesn't exist already, you've immediately created it too.

Sybren

Thanks. Is that what atomic basically means?
Yes, and also "race condition". That's why Jim Segrave's
example code uses O_EXCL with open(2).

Donn Cave, do**@u.washington.edu
Jul 17 '06 #9

Sybren Stuvel wrote:
Elmo Mäntynen enlightened us with:
Only locally. I want to be able to read/write to a single file from
multiple possibly parallel processes. Would 'touch lock' (or
something like that) work reliably (this just occured to me)?

I use a lock directory for that, os.mkdir('/var/lock/somedir').
If you use a file, you need two steps:
1) Check whether the lock-file exists
2) Create the lock-file

This is not atomic. With a directory, creating it will fail if it
already exists. This means you can atomically check for the lock, and
if it doesn't exist already, you've immediately created it too.
`Pathutils <http://www.voidspace.org.uk/python/pathutils.html>`_ has a
simple interface to a system like this.

Apparently not all platforms guarantee that attempts to create a
directory will fail if the directory already exists - so pathutils does
*slightly* more, but it's the same idea.

All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

>
Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Jul 17 '06 #10
Elmo Mäntynen wrote:
Is there something better than using fnctl? It seems a bit intimidating
with a quick look.
Although fcntl is pretty opaque, it's quite easy to use if all you want
is a simple exclusive lock for all your data. The thing to keep in
mind is, you don't have to lock every file you want exclusive access
to. In fact, doing that provides no added security (since it's an
advisory lock and programs are free to ignore it). For simple cases,
locking one file and only accessing your data if you have that lock
works, and is very simple.

What I usually do is touch an empty file (say, "lockfile") in my data
directory. I don't access any files in that directory unless I have a
lock to the lockfile. This is done simply with (untested):

import fcntl

f = open("/path/to/data/directory/lockfile","r")
try:
fcntl.flock(f.fileno(),fcntl.LOCK_EX)
...access data freely here...
finally:
f.close()

Closing the file should release the lock (unless you have a truly
horrible operating system).
Carl Banks

Jul 17 '06 #11
pa************@gmail.com wrote:
>
>ith a quick look.


f = open("/path/to/data/directory/lockfile","r")
try:
fcntl.flock(f.fileno(),fcntl.LOCK_EX)
...access data freely here...
finally:
f.close()

Closing the file should release the lock (unless you have a truly
horrible operating system).

I also find that fcntl has problems with NFS (or at least, *I* had
problems using the python fcntl module and nfs - could be that horrible
operating system, but doing things like that over nfs can be tricky).
-carl

--

Carl J. Van Arsdall
cv*********@mvista.com
Build and Release
MontaVista Software

Jul 17 '06 #12

Carl J. Van Arsdall wrote:
pa************@gmail.com wrote:

f = open("/path/to/data/directory/lockfile","r")
try:
fcntl.flock(f.fileno(),fcntl.LOCK_EX)
...access data freely here...
finally:
f.close()

Closing the file should release the lock (unless you have a truly
horrible operating system).
I also find that fcntl has problems with NFS (or at least, *I* had
problems using the python fcntl module and nfs - could be that horrible
operating system, but doing things like that over nfs can be tricky).
Ah, that's a tough one.

Apparently, you could lock files on NFS if both the client OS and NFS
server are up to the task (i.e., sufficiently recent), but good luck
getting that to fly. And, with NFS, even some of the seemingly
foolproof methods like "lock directories" aren't necessarily going to
work. Cross your fingers and hope you have a solid NFS server and
well-behaved clients.
Carl Banks

Jul 17 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Mr. B | last post by:
In my application which allows a user to open specific AutoCAD script files (SCR extension), I want to intoduce a listing of the 10 most recently opened files. I know of at least two ways that I...
3
by: Steven Burn | last post by:
The application; Service on my webserver that allows a user to upload their HOSTS file for functions to verify the contents are still valid. Uses; 1. XMLHTTP (MSXML2) 2. FileSystemObject...
7
by: Sunny | last post by:
Hi, I can not understend completely the lock statement. Actally what is locked: 1. the part of the code between {...} or 2. the object in lock() In the docs is written: for 1: The lock...
18
by: UJ | last post by:
Folks, We provide custom content for our customers. Currently we put the files on our server and people have a program we provide that will download the files. These files are usually SWF, HTML or...
9
by: csharpula csharp | last post by:
Hello, I want to lock a boolian variable but it's not possible in c#,is there a way to convert it to something that is possible to lock? Thank you! *** Sent via Developersdex...
4
by: UJ | last post by:
What's the easiest/best way to open a single file from multiple applications but so only one can read it at a time? I tried a mutex but had problems. I noticed there is something called a...
20
by: Kurt | last post by:
Below is a class that can accessed from multiple threads and I want the class to be thread safe. I have a private timer member whose interval can be changed by different threads. Which is the correct...
8
by: VJ | last post by:
I want to put a lock on my App's data directory (and all subdirectories below) when my application launches, so you can't delete through explorer or any other program. How is that possible. VJ
94
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.