java和c 互斥文件锁问题

转载 2018年04月17日 21:45:55

地址:https://blog.csdn.net/vs2008_cff/article/details/72853152

最近调项目需要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 READ178408:01:273840701073742826107374233525:
FLOCK ADVISORY WRITE81500:0f:97720 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


进程间同步--互斥量和文件锁

互斥量mutex 进程间也可以使用互斥锁,来达到同步的目的。但应在pthread_mutex_init初始化之前,修改其属性为进程间共享。mutex的属性修改函数主要有以下几个。 主要应用函数: ...
  • lzjsqn
  • lzjsqn
  • 2016-12-28 12:56:23
  • 1493

java实现多个线程互斥访问文件

两个线程利用共享文件传递信息时,需要给文件加锁,实现文件的互斥访问。可以通过FileChannel和FileLock类实现文件的加锁操作。 注意事项: 当写线程对文件加锁后,可以对文件利用FileOu...
  • B08514
  • B08514
  • 2014-01-04 22:20:25
  • 2225

Linux互斥与同步应用(六):文件锁

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途】             当一个系统中存在...
  • gentleliu
  • gentleliu
  • 2015-01-06 23:43:35
  • 1630

Python 多进程间文件锁的跨平台实现方法

引言 在Python中编写多进程间共同读写文件的过程中,需要对文件句柄进行互斥操作,否则造成文件读写混乱或者损坏。在Posix环境下(Linux/Unix)下,可以直接调用fcntl模块进行控制,Wi...
  • thomashtq
  • thomashtq
  • 2015-03-23 17:24:38
  • 2203

PHP并发进入需互斥代码

现象:与盛大对接充值出现错误。 充值接口行为:1.查充值log是否已有相同单号2.充值3.插入充值log,log中单号字段是uniq的。 php可能并发进入1,都通过检查,然后两个一起充值成功,最后插...
  • lqk1985
  • lqk1985
  • 2011-03-11 11:12:00
  • 2697

Linux多进程之间的文件锁详解

之前对于文件的操作通常在一个进程中完成,最近需要在两个进程中对同一个文件进行操作。故想到了文件锁。linux下可以使用flock()函数对文件进行加锁解锁等操作。简单介绍下flock()函数: 1....
  • wangbaochu
  • wangbaochu
  • 2015-09-18 15:38:17
  • 4327

NFS文件锁的问题

步骤: 1. 安装NFS服务器 2.客户端mount -t nfs ... ... 3.程序tryLock 出现问题: no available  lock 解决: ...
  • smst1987
  • smst1987
  • 2011-10-20 15:21:14
  • 1252

linux C语言实现文件锁之flock

一:flock函数特点: 1.flock只能加全局锁。 2.当一个进程用flock给一个文件加锁时,用另一个进程再给这个文件加锁,它会阻塞或者也可以返回加锁失败(可以自己设置)。 3.当给一个文件加f...
  • tao546377318
  • tao546377318
  • 2016-12-22 11:04:57
  • 2161

Linux C:多进程文件操作之文件锁

flock函数可以锁定文件,避免多个进程对同个文件进行操作时出现数据出错。flock的用法是在打开文件后对文件读写前调用flock函数上锁,文件操作完后flock解锁,但需注意另一个进程操作同个文件时...
  • qq_35535992
  • qq_35535992
  • 2016-10-19 21:07:46
  • 1720

C语言文件与目录(五)文件锁

1)文件锁定 所谓的文件锁定,指的是以独占的方式打开文件。一个程序打开文件以后,其它的程序不能读取或写入文件。文件锁定有利于文件内容的一致性。本节将讲解文件的锁定权限问题。 文件锁定的理解:当多个程序...
  • loophome
  • loophome
  • 2015-11-06 14:17:47
  • 1951
收藏助手
不良信息举报
您举报文章:java和c 互斥文件锁问题
举报原因:
原因补充:

(最多只允许输入30个字)