2012-12-27 23 views
5

Mam dwa procesy, które mogą uzyskać dostęp do tego samego pliku i chcą zaimplementować blokowanie plików. Problem polega na tym, że jeden proces jest napisany w java, a drugi w C i nie jest jasne, w jaki sposób blokowanie niskiego poziomu jest realizowane po stronie Java. Platforma to Solaris 10. Próbowałem wprowadzić blokowanie pliku, aby zapobiec aktualizacji przez proces Java, podczas gdy proces C czyta ten plik. Mój pomysł polegał na próbie uzyskania blokady z kodu java 10 razy, a dopiero potem bezwarunkowego zapisu do pliku (założyłem, że blokada była blokadą doradczą). Jednak metoda tryLock java przełamuje blokadę procesu C przy drugiej próbie i zniekształca odczyt.Czy metoda tryLock() FileChannel sprawdza blokady lub po prostu je zrywa?

Oto kod, uproszczony (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){ 
      ..... 
     } 

    } 

kod C używa 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); 

Czy tryLock() naprawdę sprawdza blokady?

Odpowiedz

0

Nie jestem pewien, czy to rozwiąże twój problem, czy nie, ale w przykładach, które widziałem, pole l_pid struktury stada było ustawione jak poniżej.

fl.l_pid = getpid(); 

W pytaniu nie ustawiasz tego pola. Spróbuj sprawdzić, czy to ma znaczenie. Mam nadzieję, że to pomaga.

+0

Niestety to nie pomogło. W każdym razie, dzięki za odpowiedź. – homerski