linux之fcntl函数解析

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);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fulinux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值