java和c 互斥文件锁问题

  最近调项目需要java和c访问同一个文件,涉及到文件锁问题。最开始java能识别java加的文件锁,c能识别c加的锁。但c怎么也识别不了java锁,java也识别不了c的。

通过各种查找终于找到了问题的解决方案,在一个外国网站上发现了这个提示:

Try this:
(1) Write a small java program that locks a file and sleeps (or otherwise stops executing).
(2) cat /proc/locks
(3) You'll see lines like the following:
POSIX ADVISORY READ 1784 08 : 01 : 27384070 1073742826 1073742335 25 :
FLOCK ADVISORY WRITE 815 00 : 0f : 9772 0 EOF
Identify your process ID from column 5. If column 2 is FLOCK then  flock  is being used. If it is POSIX then column 2 will be POSIX, indicating fcntl (or  lockf  which is build on top of  fcntl ) is being used.
If java has to choose one or the other then POSIX would be the sensible choice as it supports record locking.
按照此方法发现c用的是 FLOCK,java 用的是 POSIX 找到问题所在了。c换POSIX 锁。

附加可行的例子代码(注意不同的系统上锁的方式是不一样的, 请在你的linux里头用上面的 cat /proc/locks查看你加锁的方式。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Date;
import java.io.*;


public class FileLockTest {


    public static void main(String[] args){
        FileChannel channel = null;
        FileLock lock = null;
        File file=new File("file_lock.test"); 
        try {
            //1. 对于一个只读文件通过任意方式加锁时会报NonWritableChannelException异常
            //2. 无参lock()默认为独占锁,不会报NonReadableChannelException异常,因为独占就是为了写
            //3. 有参lock()为共享锁,所谓的共享也只能读共享,写是独占的,共享锁控制的代码只能是读操作,当有写冲突时会报NonWritableChannelException异常
            //channel = new FileOutputStream("file_lock.test",true).getChannel();
            RandomAccessFile raf = new RandomAccessFile(file,"rw");

            //在文件末尾追加内容的处理
            channel = raf.getChannel();

while(true){    
                //try {  
                    lock = channel.lock();  
System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");
                    break;  
                //}
//catch (Exception e) {  
                //     System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");   
                //     Thread.sleep(2000);    
                //} 
            }
            //获得锁方法一:lock(),阻塞的方法,当文件锁不可用时,当前进程会被挂起
            //lock = channel.lock();//无参lock()为独占锁
            //lock = channel.lock(0L, Long.MAX_VALUE, true);//有参lock()为共享锁,有写操作会报异常


            //获得锁方法二:trylock(),非阻塞的方法,当文件锁不可用时,tryLock()会得到null值
            //do {
            //  lock = channel.tryLock();
            //} while (null == lock);


            //互斥操作
            //ByteBuffer sendBuffer=ByteBuffer.wrap((new Date()+" 写入\n").getBytes());
            //channel.write(sendBuffer);
            Thread.sleep(30000);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (lock != null) {
                try {
                    lock.release();
                    lock = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


            if (channel != null) {
                try {
                    channel.close();
                    channel = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}



/* 
 * write_lock.c 
 * 
 *  Created on: 2012-7-17 
 *      Author: liwei.cai 
 */  
#include <unistd.h>  
#include <sys/file.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <stdio.h>  
#include <stdlib.h>


int lock_set(int fd, int type);  
  
int main()  
{  
    int fd;  
  
    //首先打开文件  
    fd = open("./file_lock.test", O_RDWR|O_CREAT, 0644);  
    if (fd < 0)  
    {  
        printf("Open file error!\n");  
        exit(1);  
    }  
    //给文件上写入锁  
    lock_set(fd, F_WRLCK);  
    getchar();
    //给文件解锁  
    lock_set(fd, F_UNLCK);  
    getchar();  
    close(fd);  
    exit(0);  





/* 
 * lock_set.c 
 * 
 *  Created on: 2012-7-17 
 *      Author: liwei.cai 
 */  
int lock_set(int fd, int type)  
{  
    struct flock old_lock, lock;  
    lock.l_whence = SEEK_SET;  
    lock.l_start = 0;  
    lock.l_len = 0;  
    lock.l_type = type;  
    lock.l_pid -1;  
  
    //判断文件是否上锁  
    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);  
        }  
    }  
    //l_type 可能已被F_FETLK修改过  
    lock.l_type = type;  
  
    //根据不同的type值进行阻塞式上锁或解锁  
    if((fcntl(fd, F_SETLKW, &lock)) < 0)  
    {  
        printf("Lock failed:type = %d\n", lock.l_type);  
        return 1;  
    }  
  
    switch(lock.l_type)  
    {  
    case F_RDLCK:  
        {  
            printf("Read lock set by %d \n", getpid());  
        }  
        break;  
    case F_WRLCK:  
        {  
            printf("Write lock set by %d \n", getpid());  
        }  
        break;  
    case F_UNLCK:  
        {  
            printf("Release lock by %d \n", getpid());  
            return 1;  
        }  
        break;  
    default:  
        break;  
    }  
    return 0;  
}  


引用网址 :

http://blog.csdn.net/zy531/article/details/51735718

http://blog.csdn.net/cailiwei712/article/details/7754723

https://stackoverflow.com/questions/23562369/is-a-java-filelock-a-posix-advisory-fcntl-lock

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值