• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 270
  • Last Modified:

Locking a file

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
victory323
Asked:
victory323
  • 4
  • 3
  • 3
  • +6
1 Solution
 
victory323Author Commented:
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
 
NosfedraCommented:
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
 
akshayxxCommented:
try semaphores ... to my knowledge they can provide system wide synchronization/locking mechanism

not sure abt windows .. but available on most linux
0
Industry Leaders: 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!

 
akshayxxCommented:
>>but available on most linux
i meant most Unix and similar systems
0
 
Kent OlsenData Warehouse Architect / DBACommented:
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
 
rooster_0429Commented:
for simple mutual exclusion use mutexes.
0
 
KocilCommented:
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
 
victory323Author Commented:
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
 
KocilCommented:
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
 
ecwCommented:
man flock
man lockf
0
 
ewestCommented:
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
 
victory323Author Commented:
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
 
victory323Author Commented:
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
 
KocilCommented:
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
 
Kent OlsenData Warehouse Architect / DBACommented:
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
 
ewestCommented:
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
 
ewestCommented:
...oh and just to be clear: that sample code contains only the barest of error checking/handling.
0
 
jmcgOwnerCommented:
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

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!

  • 4
  • 3
  • 3
  • +6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now