我有两个进程可以同时访问同一个文件并希望实现文件锁定。问题似乎是一个进程是用 java 编写的,另一个是用 C 编写的,并且不清楚在 java 端是如何实现低级锁定的。平台是 Solaris 10。我试图在文件上引入锁定,以防止 Java 进程在 C 进程读取文件时进行更新。我的想法是尝试从 java 代码中获取锁 10 次,然后才无条件地写入文件(我假设锁类型是咨询锁)。但是,java tryLock() 在第二次尝试时会破坏 C 进程的锁定并破坏读取。
这是简化的代码(Java):
int iAttemptCnt = 0;
FileChannel wchannel = new FileOutputStream(new File(fileName), false).getChannel();;
FileLock flock;
while(true){
try{
MyLog.log(MyLog.LVL_INFO, "attempt to lock file");
if( (flock = wChannel.tryLock()) == null ){
// lock held by another program
if(++iAttemptCnt >= 10
break;
}
else{
MyLog.log(MyLog.LVL_INFO, " file locked");
break;
}
}catch(OverlappingFileLockException ofle){
.......
if(++iAttemptCnt >= 10 ){
...
break;
}
}catch(IOException ioe){
throw new IOException("failed to lock the file");
}
try{
MyLog.log(MyLog.LVL_INFO, "File already locked, retrying in one second");
Thread.sleep(1000);
}catch(InterruptedException ie){
.....
}
}
C 代码使用 fcntl:
fd = open(filename, O_RDONLY);
.....
lck.l_type = F_RDLCK;/* F_RDLCK setting a shared or read lock */
lck.l_whence = 0; /* offset l_start from beginning of file */
lck.l_start = 0LL;
lck.l_len = 0LL; /* until the end of the file address space */
....
while( fcntl(fd, F_SETLK64, &lck) < 0){
if( errno == EAGAIN )
....
else if (errno == EIO )
...
else if( errno == ENOLCK)
...
else if (errno == EDEADLK)
...
if(++ii == 10 ){
break;
}
...
sleep(1);
}
MyLongLastingRead();
...
lck.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lck);
close(fd);
tryLock()
真的检查锁吗?