472,982 Members | 2,233 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,982 software developers and data experts.

fcntl problems

I'm having a number of problems with the fcntl module. First off, my
system info:

Mac OS X
Darwin igskcicglthearn.cr.usgs.gov 8.10.1 Darwin Kernel Version
8.10.1: Wed May 23 16:33:00 PDT 2007; root:xnu-792.22.5~1/RELEASE_I386
i386 i386
Python 2.5.1 (built from source)

OK, the weirdness:

First of all, if I try this:
file = open("counter.txt","w+")
fcntl.flock(file.fileno(), fcntl.LOCK_NB)

I get this:
---------------------------------------------------------------------------
<type 'exceptions.IOError' Traceback (most recent call
last)
/Users/mhearne/src/python/<ipython consolein <module>()
<type 'exceptions.IOError'>: [Errno 9] Bad file descriptor

However, if I try this:
fcntl.flock(file.fileno(), fcntl.LOCK_EX)

I get no errors.

Proceeding forward with the locked file, let's say I do the above in
Python interactive Process A. Then in python interactive Process B, I
repeat the "open" function on the same file with the same
permissions. Then, in each process, I write some text to the file
using the write() method. After closing the file in both processes,
the only text I see in the file is from Process B!

According to my Python Cookbook:
"Exclusive lock: This denies all _other_ processes both read and write
access to the file."

I seem to be experiencing the reverse of that description. Is this my
lack of understanding, or have I discovered a bug?

Thanks,

Mike

Aug 30 '07 #1
9 5268
On Aug 30, 4:19 pm, "mhearne808[insert-at-sign-here]gmail[insert-dot-
here]com" <mhearne...@gmail.comwrote:
I'm having a number of problems with the fcntl module. First off, my
system info:

Mac OS X
Darwin igskcicglthearn.cr.usgs.gov 8.10.1 Darwin Kernel Version
8.10.1: Wed May 23 16:33:00 PDT 2007; root:xnu-792.22.5~1/RELEASE_I386
i386 i386
Python 2.5.1 (built from source)

OK, the weirdness:

First of all, if I try this:
file = open("counter.txt","w+")
fcntl.flock(file.fileno(), fcntl.LOCK_NB)

I get this:
---------------------------------------------------------------------------
<type 'exceptions.IOError' Traceback (most recent call
last)
/Users/mhearne/src/python/<ipython consolein <module>()
<type 'exceptions.IOError'>: [Errno 9] Bad file descriptor

However, if I try this:
fcntl.flock(file.fileno(), fcntl.LOCK_EX)

I get no errors.

Proceeding forward with the locked file, let's say I do the above in
Python interactive Process A. Then in python interactive Process B, I
repeat the "open" function on the same file with the same
permissions. Then, in each process, I write some text to the file
using the write() method. After closing the file in both processes,
the only text I see in the file is from Process B!

According to my Python Cookbook:
"Exclusive lock: This denies all _other_ processes both read and write
access to the file."

I seem to be experiencing the reverse of that description. Is this my
lack of understanding, or have I discovered a bug?

Thanks,

Mike
I've been doing some experiments, and here are some specific examples
to try. I'll designate the two interactive python processes as PA and
PB. Both processes were started in the same directory. Here goes:
PA: import fcntl
PA: f = open("foo.txt","w+")
PA: fcntl.flock(f.fileno(),fcntl.LOCK_EX)
PA: f.write("text1\n")
PB: f = open("foo.txt","w+")
PB: f.write("text2\n")
PA: f.close()
PB: f.close()

contents of foo.txt are:
text2

Second experiment:

PA: f = open("foo.txt","w+")
PA: fcntl.flock(f.fileno(),fcntl.LOCK_EX)
PB: f = open("foo.txt","w+")
PA: f.write("text1\n")
PB: f.write("text2\n")
PA: f.write("text3\n")
PB: f.close()
PA: f.write("text4\n")
PA: f.close()

contents of foo.txt are:
text1
text3
text4

Third experiment:
PA: f = open("foo.txt","w+")
PA: fcntl.flock(f.fileno(),fcntl.LOCK_EX)
PA: f.write("text1\n")
PB: f = open("foo.txt","w+")
PB: f.write("text2\n")
PB: f.close()
PA: f.close()

contents of foo.txt are:
text1

Fourth experiment:
PA: f = open("foo.txt","w+")
PA: f.write("text1\n")
PB: f = open("foo.txt","w+")
PB: f.write("text2\n")
PB: f.close()
PA: f.close()

contents of foo.txt are:
text1
>From these last two experiments I can only conclude that file locking
isn't doing a durned thing.

What's going on?

--Mike

Aug 30 '07 #2
On 8/30/07, mhearne808 wrote:
I'm having a number of problems with the fcntl module.
Read this first: http://linux.die.net/man/2/flock
First of all, if I try this:
file = open("counter.txt","w+")
fcntl.flock(file.fileno(), fcntl.LOCK_NB)

I get this:
---------------------------------------------------------------------------
<type 'exceptions.IOError' Traceback (most recent call
last)
/Users/mhearne/src/python/<ipython consolein <module>()
<type 'exceptions.IOError'>: [Errno 9] Bad file descriptor
That should be:
>>fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
Proceeding forward with the locked file, let's say I do the above in
Python interactive Process A. Then in python interactive Process B, I
repeat the "open" function on the same file with the same
permissions. Then, in each process, I write some text to the file
using the write() method. After closing the file in both processes,
the only text I see in the file is from Process B!
This is due to two issues: caching and file position. When you open
the file in both processes as 'w+', they are both positioned at the
*current* EOF, but from that point on the offset is not externally
influenced. The correct sequence of events should be:
- open file in mode w+
- obtain exclusive lock
- f.seek(0, 2) # (to end of file)
- write to file
- f.flush() # or f.close()
- release lock
Is this my lack of understanding, or have I discovered a bug?
If you find yourself asking this question, it's too often the former :)

-Miles
Aug 31 '07 #3
Sorry, that last quote-only reply was accidental. :)

On 8/30/07, mhearne808 wrote:
I've been doing some experiments, and here are some specific examples
to try.
[snipped examples]
From these last two experiments I can only conclude that file locking
isn't doing a durned thing.

What's going on?
File locking isn't doing a durned thing in those cases because you're
only obtaining the lock from a single process.
According to my Python Cookbook:
"Exclusive lock: This denies all _other_ processes both read and write
access to the file."
This is only for mandatory locking; POSIX flock is advisory locking,
which states: "Only one process may hold an exclusive lock for a given
file at a given time." Advisory locks don't have any effect on
processes that don't use locks. Mandatory locks are kernel enforced,
but non-POSIX and not available in Mac OS X.

-Miles
Aug 31 '07 #4
On Aug 31, 12:23 am, Miles <semantic...@gmail.comwrote:
Sorry, that last quote-only reply was accidental. :)

On 8/30/07, mhearne808 wrote:
I've been doing some experiments, and here are some specific examples
to try.

[snipped examples]
From these last two experiments I can only conclude that file locking
isn't doing a durned thing.
What's going on?

File locking isn't doing a durned thing in those cases because you're
only obtaining the lock from a single process.
According to my Python Cookbook:
"Exclusive lock: This denies all _other_ processes both read and write
access to the file."

This is only for mandatory locking; POSIX flock is advisory locking,
which states: "Only one process may hold an exclusive lock for a given
file at a given time." Advisory locks don't have any effect on
processes that don't use locks. Mandatory locks are kernel enforced,
but non-POSIX and not available in Mac OS X.

-Miles
I think I'm still confused. Maybe I should explain the behavior that
I want, and then figure out if it is possible.

I have a script that will be run from a cron job once a minute. One
of the things this script will do is open a file to stash some
temporary results. I expect that this script will always finish its
work in less than 15 seconds, but I didn't want to depend on that.
Thus I started to look into file locking, which I had hoped I could
use in the following fashion:

Process A opens file foo
Process A locks file foo
Process A takes more than a minute to do its work
Process B wakes up
Process B determines that file foo is locked
Process B quits in disgust
Process A finishes its work

Since I couldn't figure out file locking, I decided to just have
Process A create a "pid" file in the directory - analogous to the
"Occupied" sign on an airplane bathroom. This works, but it seems a
little hacky.

--Mike

Aug 31 '07 #5
On 8/31/07, mhearne808 wrote:
I have a script that will be run from a cron job once a minute. One
of the things this script will do is open a file to stash some
temporary results. I expect that this script will always finish its
work in less than 15 seconds, but I didn't want to depend on that.
Thus I started to look into file locking, which I had hoped I could
use in the following fashion:

Process A opens file foo
Process A locks file foo
Process A takes more than a minute to do its work
Process B wakes up
Process B determines that file foo is locked
Process B quits in disgust
Process A finishes its work
That would look like (untested):

import fcntl, sys
f = open('foo', 'w+')
try:
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError, e:
if e.args[0] == 35:
sys.exit(1)
else:
raise
f.seek(0, 2) # seek to end
# do your thing with the file
f.flush()
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
f.close()

-Miles
Aug 31 '07 #6
"mhearne808[insert-at-sign-here]gmail[insert-dot-here]com" <mh********@gmail.comwrites:
I think I'm still confused.
What Miles tried to tell you is that you should call fcnt.flock from
both PA and PB. In the example you posted, you failed to call it from
PB. No lock call, so no locking happened.
I have a script that will be run from a cron job once a minute. One
of the things this script will do is open a file to stash some
temporary results. I expect that this script will always finish its
work in less than 15 seconds, but I didn't want to depend on that.

Thus I started to look into file locking, which I had hoped I could
use in the following fashion:

Process A opens file foo
Process A locks file foo
Process A takes more than a minute to do its work
Process B wakes up
Process B determines that file foo is locked
Process B quits in disgust
Process A finishes its work
File locking supports that scenario, as you suspected. You need to
use flock with LOCK_EX|LOCK_NB. If the call succeeds, you got the
lock. If you get an exception whose errno is EWOULDBLOCK, you quit in
disgust.
Aug 31 '07 #7
On 8/31/07, mhearne808 wrote:
Looking at my flock(3) man page, I'm guessing that "35" is the error
code for EWOULDBLOCK. Which system header file am I supposed to look
in to figure that magic number out?
I got the error number by looking at the IOError exception raised when
playing with the interactive interpreter, but I really should have
written:

from errno import EWOULDBLOCK
....
if e.args[0] == EWOULDBLOCK:
....

- Miles
Aug 31 '07 #8
In article <11**********************@o80g2000hse.googlegroups .com>,
"mhearne808[insert-at-sign-here]gmail[insert-dot-here]com"
<mh********@gmail.comwrote:
Looking at my flock(3) man page, I'm guessing that "35" is the error
code for EWOULDBLOCK. Which system header file am I supposed to look
in to figure that magic number out?
On a MacOS system, you can find them in /usr/include/sys/errno.h
On a Linux system, try /usr/include/asm-generic/errno.h

However, if you're writing in Python, you will probably have an easier
time using the "errno" module, e.g.,

] import errno
] errno.errorcode[35]
'EDEADLOCK'

Note that some codes have multiple names (e.g., EAGAIN and EWOULDBLOCK)
so that this lookup may not return exactly the name you're expecting.

Cheers,
-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Aug 31 '07 #9
In message <ma**************************************@python.o rg>, Miles
wrote:
except IOError, e:
if e.args[0] == 35:
Why not

except IOError, (ErrNo, Msg) :
if ErrNo == errno.EAGAIN :
Aug 31 '07 #10

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

Similar topics

2
by: Meyer, Tony | last post by:
(I did try to google for an answer to this, but couldn't find anything, although plenty of instances of the warning). I don't understand this warning: >>> import fcntl C:\Program...
6
by: Pierre Rouleau | last post by:
Hi all! I am using Python 2.3.1 on Win32 (NT, 2000). Whenever a file imports the standard tempfile module, Python 2.3.1 issues the following warning: C:\Python23\lib\fcntl.py:7:...
0
by: Ryan Grow | last post by:
Hi, I'm trying to use fcntl to set an existing file descriptor to be nonblocking. This contrived example exhibits the behavior of python that is preventing me from doing this: import os,...
11
by: Chris Green | last post by:
Hey folks, Is there anyway for a signal handler in python to get the information from a 3 argument signal handler rather than just the signal number and stack frame? I've got an application...
4
by: Omid Fatemi | last post by:
I followed discussion in the group about this problem: ImportError: No module named fcntl I found out there are two modules: FCNTL fcntl the first one is obsolete and shouldn't be used. But...
3
by: thakadu | last post by:
The following code works as expected when run in the main body of a python script (ver 2.3.5) on OpenBSD v3.8. but when it is in the body of a function definition it does not work. It does not...
5
by: marcello | last post by:
Hello I need to do this: 1 opening a file for writing/appending 2 to lock the file as for writing (i mean: the program that lock can keep writing, all others programs can't ) 3 wtite and...
0
by: Mitko Haralanov | last post by:
I am trying to use the advisory locking with fcntl over NFS (thus, me choosing fcntl instead of flock and friends). I have the following code: lockdata = struct.pack ("hhllhh", fcntl.F_RDLCK, 0,...
2
by: xucs007 | last post by:
I ran following 2 programs (lock1, lock2) at almost same time, to write either "123456", or "222" to file "aaa" at the same time. But I often just got "222456" in "aaa" . Is this a bug of python...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 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: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.