您的位置:首页 > 运维架构 > Linux

linux之fcntl函数解析

2013-07-30 16:40 323 查看
1、写入锁实例:

[lingyun@localhost fcntl]$ cat fcntl_write.c 

/*********************************************************************************

 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 

 *                  All rights reserved.

 *

 *       Filename:  fcntl_write.c

 *    Description:  This file 

 *                 

 *        Version:  1.0.0(07/30/2013~)

 *         Author:  fulinux <fulinux@sina.com>

 *      ChangeLog:  1, Release initial version on "07/30/2013 04:02:42 PM"

 *                 

 ********************************************************************************/

#include <unistd.h>

#include <sys/file.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <stdlib.h>

void lock_set(int fd, int type)

{

    struct flock lock;

    lock.l_whence   = SEEK_SET;

    lock.l_start    = 0;

    lock.l_len      = 0;

    while(1)

    {

        lock.l_type     = type;

        if((fcntl(fd, F_SETLK, &lock)) == 0)

        {

            if(lock.l_type == F_RDLCK)

                printf("read lock set by %d\n", getpid());

            else if(lock.l_type == F_WRLCK )

                printf("write lock set by %d\n", getpid());

            else if(lock.l_type == F_UNLCK)

                printf("release lock by %d\n", getpid());

            return;

        }

        

        fcntl(fd, F_GETLK, &lock);

        if(lock.l_type != F_UNLCK)

        {

            if(lock.l_type == F_RDLCK)

                printf("read lock already set by %d\n", lock.l_pid);

            else if(lock.l_type == F_WRLCK)

                printf("write lock already set by %d\n",lock.l_pid);

            getchar();

        }

    }

}

int main(void)

{

    int fd;

    fd = open("hello",O_RDWR | O_CREAT, 0666);

    if(fd < 0)

    {

        perror("open");

        exit(1);

    }

    lock_set(fd, F_WRLCK);

    getchar();

    lock_set(fd, F_UNLCK);

    getchar();

    close(fd);

    exit(0);

    

}
[lingyun@localhost fcntl]$ 

[lingyun@localhost fcntl]$ touch hello

[lingyun@localhost fcntl]$ ls

fcntl_write.c  hello

[lingyun@localhost fcntl]$ gcc fcntl_write.c 

[lingyun@localhost fcntl]$ ./a.out 

write lock set by 2941

release lock by 2941

[lingyun@localhost fcntl]$ 

在两个终端上同时运行:

第一个:

[lingyun@localhost fcntl]$ ./a.out 

write lock set by 2956

第二个:

[lingyun@localhost fcntl]$ ./a.out 

write lock already set by 2956

write lock already set by 2956

第一个:

[lingyun@localhost fcntl]$ ./a.out 

write lock set by 2956

release lock by 2956

第二个:

[lingyun@localhost fcntl]$ ./a.out 

write lock already set by 2956

write lock already set by 2956

write lock set by 2916

release lock by 2916

互斥锁。

2、读取锁实例:

[lingyun@localhost fcntl_2]$ cat fcntl_read.c 

/*********************************************************************************

 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 

 *                  All rights reserved.

 *

 *       Filename:  fcntl_write.c

 *    Description:  This file 

 *                 

 *        Version:  1.0.0(07/30/2013~)

 *         Author:  fulinux <fulinux@sina.com>

 *      ChangeLog:  1, Release initial version on "07/30/2013 04:02:42 PM"

 *                 

 ********************************************************************************/

#include <unistd.h>

#include <sys/file.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <stdlib.h>

void lock_set(int fd, int type)

{

    struct flock lock;

    lock.l_whence   = SEEK_SET;

    lock.l_start    = 0;

    lock.l_len      = 0;

    while(1)

    {

        lock.l_type     = type;

        if((fcntl(fd, F_SETLK, &lock)) == 0)

        {

            if(lock.l_type == F_RDLCK)

                printf("read lock set by %d\n", getpid());

            else if(lock.l_type == F_WRLCK )

                printf("write lock set by %d\n", getpid());

            else if(lock.l_type == F_UNLCK)

                printf("release lock by %d\n", getpid());

            return;

        }

        

        fcntl(fd, F_GETLK, &lock);

        if(lock.l_type != F_UNLCK)

        {

            if(lock.l_type == F_RDLCK)

                printf("read lock already set by %d\n", lock.l_pid);

            else if(lock.l_type == F_WRLCK)

                printf("write lock already set by %d\n",lock.l_pid);

            getchar();

        }

    }

}

int main(void)

{

    int fd;

    fd = open("hello",O_RDWR | O_CREAT, 0666);

    if(fd < 0)

    {

        perror("open");

        exit(1);

    }

    lock_set(fd, F_RDLCK);

    getchar();

    lock_set(fd, F_UNLCK);

    getchar();

    close(fd);

    exit(0);

    

}

[lingyun@localhost fcntl_2]$ 

第一个终端:

[lingyun@localhost fcntl_2]$ ./a.out 

read lock set by 3158

release lock by 3158

第二个终端:

[lingyun@localhost fcntl_2]$ ./a.out 

read lock set by 3147

release lock by 3147

不是排斥的

三、同时测试写入锁和读取锁实例

让上面两个程序打开同一个文件。

第一个终端:

[lingyun@localhost fcntl_2]$ ./a.out 

read lock set by 3238

第二个终端:

[lingyun@localhost fcntl_1]$ ./a.out           

read lock already set by 3238

可见被读取锁上锁后写入锁无法上锁,反之亦然。

[lingyun@localhost fcntl_3]$ cat fcntl.c 

/*********************************************************************************

 *      Copyright:  (C) 2013 fulinux<fulinux@sina.com> 

 *                  All rights reserved.

 *

 *       Filename:  fcntl.c

 *    Description:  This file 

 *                 

 *        Version:  1.0.0(08/01/2013~)

 *         Author:  fulinux <fulinux@sina.com>

 *      ChangeLog:  1, Release initial version on "08/01/2013 02:34:00 PM"

 *                 

 ********************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

int main(int argc, char *argv[])

{

    int     val;

    if(argc != 2)

    {

        perror("argc");

        exit(0);

    }

    if((val = fcntl(atoi(argv[1]), F_GETFL, 0)) < 0)

    {

        switch(val & O_ACCMODE)

        {

            case O_RDONLY:

                printf("read only");

                break;

            case O_WRONLY:

                printf("write only");

                break;

            case O_RDWR:

                printf("read write");

                break;

            default:

                printf("unknown access mode");

                break;

        }

        if(val & O_APPEND)

            printf(", append");

        if(val & O_NONBLOCK)

            printf(", nonblocking");

#if defined(O_SYNC)

        if(val & O_SYNC)

            printf(", synchronous writes");

#endif

#if ! defined(_POSIX_C_SOURCE) && defined(O_FSYNC)

        if(val & O_FSYNC)

            printf(", synchronous writes");

#endif

        putchar('\n');

        exit(0);

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: