C Board  

Go Back   C Board > Platform Specific Boards > Linux Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-21-2009, 07:40 AM   #1
Registered User
 
Join Date: Jul 2009
Posts: 57
Mutual Exclusion and Running a Single Copy [open,lockf,getpid]

Hi,
I'm writing a daemon and now that must be run in a single process (two instance of process should not be executed at the same time). I tried this code, but it didn't work:
Code:
    int lfp=open(LOCK_FILE, O_RDWR|O_CREAT,0640);
    if (lfp<0)
        cout << "Could not open lockfile" << endl;

    if ( lockf(lfp,F_TLOCK,0)<0 )
        exit(0); /* can not lock */
    
    /* first instance continues */

    char str[10];
    sprintf(str,"%d\n",getpid());
    write(lfp,str,strlen(str)); /* record pid to lockfile */
    close(lfp);
What's wrong?!

Thanks
hosseinyounesi is offline   Reply With Quote
Old 09-21-2009, 08:14 AM   #2
Registered User
 
valaris's Avatar
 
Join Date: Jun 2008
Location: RING 0
Posts: 468
What are the errors/problems?
valaris is offline   Reply With Quote
Old 09-21-2009, 09:12 AM   #3
Registered User
 
Join Date: Jul 2009
Posts: 57
There is no compile error, but two or more instance of the program can still be executed at the same time (simultaneously)
hosseinyounesi is offline   Reply With Quote
Old 09-21-2009, 09:36 PM   #4
Registered User
 
Join Date: Nov 2008
Posts: 75
Try using the library "unique", instead of reinventing the wheel.
MisterIO is offline   Reply With Quote
Old 09-22-2009, 01:01 AM   #5
Registered User
 
Join Date: Jul 2009
Posts: 57
"unique" library?! What do you mean?! It's a C library or ... ?!
hosseinyounesi is offline   Reply With Quote
Old 09-22-2009, 09:21 AM   #6
Registered User
 
Join Date: Nov 2008
Posts: 75
Yes, it's a c library. Debian -- Details of package libunique-1.0-0 in sid
MisterIO is offline   Reply With Quote
Old 09-22-2009, 10:57 AM   #7
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,900
Well, that's Gnome specific (with X11 dependencies). Internally it uses either Unix domain sockets or D-Bus.

>> What's wrong?!
Only thing I see wrong is that "if (lfp<0)" allows execution to continue.

gg
Codeplug is online now   Reply With Quote
Old 09-22-2009, 11:48 AM   #8
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,763
A more reliable way is to use a UNIX socket. Two processes cannot both bind to the same UNIX socket name. As part of your startup, open and bind a UNIX socket at some known location (probably somewhere in /var). If you fail to bind, you know another instance is already running.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 09-22-2009, 12:02 PM   #9
Registered User
 
Join Date: Nov 2008
Posts: 75
Quote:
Originally Posted by Codeplug View Post
Well, that's Gnome specific (with X11 dependencies). Internally it uses either Unix domain sockets or D-Bus.

>> What's wrong?!
Only thing I see wrong is that "if (lfp<0)" allows execution to continue.

gg
It's not gnome specific. It has dependencies(as can be seen from the link), but that's different from being gnome specific.
MisterIO is offline   Reply With Quote
Old 09-22-2009, 12:11 PM   #10
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,900
I would say it's "as realiable", since advisory-locks held by a process are removed when the descriptor is closed - and all descriptors are closed when the process exits. But sockets provide a comm. channel which may be useful.

Which brings up the question: Are you sure that both processes are just acquiring and releasing the lock, one after another? If the code you posted is the code you're running, then that's probably the case.

Also, you may want to ftruncate() the file once you acquire the lock to prevent any "left-overs" from previous write() of longer pids.

>> It's not gnome specific.
Sorry, GTK+, X11 dependent would be more accurate.

gg

Last edited by Codeplug; 09-22-2009 at 12:38 PM.
Codeplug is online now   Reply With Quote
Old 09-23-2009, 12:45 AM   #11
Registered User
 
Join Date: Jul 2009
Posts: 57
Quote:
channel which may be useful.
What's this?!

Quote:
Which brings up the question: Are you sure that both processes are just acquiring and releasing the lock, one after another? If the code you posted is the code you're running, then that's probably the case.
With the code I posted, two execution of the program can be executed and the lockf return 0 for each of them!!!
hosseinyounesi is offline   Reply With Quote
Old 09-23-2009, 02:16 AM   #12
Registered User
 
Join Date: Jul 2009
Posts: 57
Hi,
I used flock and it is working now
flock(2) - Linux man page
Code:
    int fd=open(LOCK_FILE, O_RDWR|O_CREAT,0640);
    if (fd<0)
        cout << "Could not open lockfile" << endl;

    int x=flock(fd,LOCK_EX | LOCK_NB);
    if( x<0 )
        exit(1);
    /* first instance continues */
hosseinyounesi is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump


All times are GMT -6. The time now is 03:49 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22