?
Solved

Locking a file

Posted on 2003-03-14
19
Medium Priority
?
269 Views
Last Modified: 2012-06-21
i'm writing a C program using client-server method, the server sends a file for the client after checking if the file is not locked. The file is locked if it is in use by onther client.

my problem is with the locking mechanism. i have tried to store the file name in a link list and if any client try to get any file , the server should check the file whether it is in the list or not.
but this did not give me a result.

please help me if you have a simple idea and show me how to do it.
 
i need it as soon as possible

thank you all
0
Comment
Question by:victory323
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +6
19 Comments
 

Author Comment

by:victory323
ID: 8135133
i've tried to increase the points but i don't have alot
please take my question into consideration.
i need it urgently
Thank you
0
 
LVL 3

Expert Comment

by:Nosfedra
ID: 8135415
What OS are you working on?
As a portable way, you could try to create another file while the file you use is locked and check from the other process if that file exists.
After finishing processing, delete the file.

But usually, this is done by shared memory mechanisms. The file creation is somewhat of an extension for semaphores: don't do anything 'till I'm doing.
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 8135621
try semaphores ... to my knowledge they can provide system wide synchronization/locking mechanism

not sure abt windows .. but available on most linux
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:akshayxx
ID: 8135628
>>but available on most linux
i meant most Unix and similar systems
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 8136434
If you're on a *nix system, you have a number of options.  I'm a fan of akshayxx's suggestion to use semaphores.

If you hope to have your application run on both *nix and Windows platforms, you might utilize the message queue and have a single task/thread manage the locks.  (This is also a good *nix solution.)

Borland's C++ has the Syncronize() method to single thread execution in an other-wise multi-threaded application.  Syncronize(LockFile()) and Syncronize(UnLockFile()) force the LockFile() and UnLockFile() methods to be run in the applications primary thread, ensuring single threaded execution.  Borland's C++ Builder supports both *nix and Windows applications


Kdo
0
 

Expert Comment

by:rooster_0429
ID: 8136953
for simple mutual exclusion use mutexes.
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8137361
As you use a client-server model, the common architecture is three-tier. Therefore locking can be done in 3 posible level.
1. Data level (file locking)
2. Server level (multithreading locking)
3. Client level (distributed locking)

File locking is the easiest. You may use some function from io.h (lock, unlock) to do this, but unfortunatelly it's not part of standad C. So it may differ from compiler to compiler.

The second is the most effective, but it higly depends on the multithreading model. You will have different implementation for Windows or Unix.

The third, you need special distributed file system locking. UNIX has NFS that support distributed locking. I'm not sure about Windows.

I suggest that you use the second option. There are several pattern/architecture for this.
1. Blackboard. You use a single global data to store the locking information. Each thread will access this global data with synchronisation (with mutex / semaphore). Fast, but high risk for deadlock.

2. Monitor. You use single thread as a monitor that access the I/O. Other threads send the request to a global mailbox (queue), the monitor gets the request one by one and services it. Slower, but stable.

I hope this intro can shape up your mind. Please tell us more about your OS / Compiler and the locking model you like before we continue the discussion.
 
0
 

Author Comment

by:victory323
ID: 8137865
i'm working on Linux mandrake.
do you mean that there are functions such as Lock and unlock if so please give me the code.
i've tried to use link list but i think i did not do it in the right way i will bring the code that i wrote and paste it soon.
thanks to all
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8140636
Great ... another Linux programmers is here !!

If you choose to File level lock, this is the manual of file locking. I can't make it shorter :)
http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_8.html#SEC146

But yeah ... send your code. I bet you are using Blackboard pattern now.
0
 
LVL 5

Expert Comment

by:ecw
ID: 8144970
man flock
man lockf
0
 
LVL 2

Expert Comment

by:ewest
ID: 8145000
A note about flock, lockf (and fcntl) -- these are process level locks. If your client/server implementation is multi-threaded these types of locks will not be of much use.
0
 

Author Comment

by:victory323
ID: 8145964
ewest.. what do you mean (( if my client/server implementation is multithreaded then flock,lockf are not much of use )).

by the way, could you please show me how are these functions work??
 thank you.
0
 

Author Comment

by:victory323
ID: 8146028
ewest.. what do you mean (( if my client/server implementation is multithreaded then flock,lockf are not much of use )).

by the way, could you please show me how are these functions work??
 thank you.
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8146118
It mean, as he said, the lock is useless between thread. If thread 1 lock it, thread 2 can still gain access. To be effective, you have to use multitasking with fork(), not multithreading with pthread().

Oh ... man, this getting complicated :)



0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 8146649
Hi Kocil,

I don't think that it's all that complicated.  Someone posts a question, declines to research the link you provided, and now wants the entire web-page pasted into a response.  :)


Victory,

Kocil pointed you to the right place.  Near the bottom of the page is a section entitled "File Locks".  It's URL is:

http://www.gnu.org/manual/glibc-2.0.6/html_chapter/libc_8.html#SEC146

Please read it.  It should be an effective solution and implement fairly easily.


Kdo
0
 
LVL 2

Accepted Solution

by:
ewest earned 160 total points
ID: 8146695
And yet more issues with flock, lockf, (and fcntl):

flock and lockf use different mechanisms to lock a file. Processes using flock are not aware that lockf has been used to lock the same file by another process.Of course, you're writing the code and would never mix flock and lockf calls. ...but a maintainer of your code might.

Although flock can under linux provide mandatory locking. It is not portable or standard. Staying with the standard implementations of flock and lockf, these provide "advisory" locks. This type of lock requires synchonization via the locking routines. A non-cooperative process can just bypass the advisory lock via an open/read/write sequence.

lockf and fcntl use the same mechanism to lock a file. In fact lockf is typically implemented by calling fcntl with the appropriate arguments.

flock can not be used to protect files accessed via NFS.


My personal preference is to use fcntl. As an example:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#ifdef DEBUG
#define DBG( args ) \
    printf args ; \
    fflush(stdout)
#else
#define DBG( args )
#endif


int
lockInit(const char *lockName, int *lockHandle)
{
    DBG(("entering lockInit: %d\n" , getpid()));

    *lockHandle = open(lockName, O_RDWR | O_CREAT,
                        S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP );

    DBG(("leaving lockInit: %d\n" , getpid()));

    if ((-1) == *lockHandle) {
        return -1;
    }

    return 0;
}

void
lockFini(int *lockHandle)
{
    DBG(("entering lockFini: %d\n" , getpid()));

    (void)close(*lockHandle);
    *lockHandle = -1;

    DBG(("leaving lockFini: %d\n" , getpid()));
}


int
lockWrite(int *lockHandle)
{
    struct flock       lockinfo;
    int rc;

    lockinfo.l_whence = SEEK_SET;
    lockinfo.l_start  = 0;
    lockinfo.l_len    = 0;
    lockinfo.l_type   = F_WRLCK;

    DBG(("entering lockWrite: %d\n" , getpid()));

    rc = fcntl(*lockHandle, F_SETLKW, &lockinfo );

    DBG(("leaving lockWrite: %d\n" , getpid()));

    return rc;
}


int
lockRelease(int *lockHandle)
{
    struct flock lockinfo;
    int rc;

    lockinfo.l_whence = SEEK_SET;
    lockinfo.l_start  = 0;
    lockinfo.l_len    = 0;
    lockinfo.l_type   = F_UNLCK;

    DBG(("entering lockRelease: %d\n" , getpid()));

    rc = fcntl( *lockHandle, F_SETLK, &lockinfo );

    DBG(("leaving lockRelease: %d\n" , getpid()));

    return rc;
}

void
do_lockTest(const char *lockfile)
{
    int lockHandle;

    if (!lockInit(lockfile, &lockHandle)) {
        printf("failed to initialize lock\n");
        exit(1);
    }

    while (1) {
        printf("..... proc %d wants the lock\n", getpid());
        if (!lockWrite(&lockHandle)) {
            printf("failed to get write lock\n");
            lockFini(&lockHandle);
            exit(1);
        }

        printf("***** proc %d has the lock\n", getpid());
        sleep(3);

        if (!lockRelease(&lockHandle)) {
            printf("failed to release lock\n");
            lockFini(&lockHandle);
            exit(1);
        }

        printf("----- proc %d gave up the lock\n", getpid());
        sleep(1);
    }

}


int
main(int argc, char **argv)
{
    int i;
    pid_t pid;

    for (i = 0; i < 3; i++) {
        pid = fork();
        switch (pid) {
        case 0:
            do_lockTest(argv[0]);
            exit(0);
            break;
        case -1:
            printf("fork failed\n");
            exit(1);
        }
    }


   wait(NULL);

   return 0;
}

Compile w/ CFLAGS=-DDEBUG

The URL posted is pretty complete from a GNU perspective. An equally useful source is the Steven's text, "Advanced Programming in the Unix Environment"; Prentice Hall publ.
0
 
LVL 2

Expert Comment

by:ewest
ID: 8146722
...oh and just to be clear: that sample code contains only the barest of error checking/handling.
0
 
LVL 20

Expert Comment

by:jmcg
ID: 10131966
Nothing has happened on this question in more than 9 months. It's time for cleanup!

My recommendation, which I will post in the Cleanup topic area, is to
accept answer by ewest.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question