2014-12-14 21 views
10

Sto imparando Rust da circa 3 ore e non riesco a trovare nulla che assomigli al blocco dei file (sai, come alcuni programmi usano in Linux per impedire l'esecuzione di più istanze).C'è un blocco di file in Rust?

E.g. in Python, userei questo modulo: https://github.com/openstack/pylockfile

Sto trascurando funzionalità simili in Rust, o dovrei solo implementarlo da zero?

Non pigro, solo cercando di reinventare le ruote più piccole possibile.

+2

C'è venuto [codice per avviare da] (https://github.com/rust-lang/rust/blob/master/src/librustdoc/flock.rs) in rustdoc. Dice "Questo non è pensato per essere nella libreria standard". – Shepmaster

+2

Penso che potrebbe essere necessario implementarlo da zero. Il modulo IO/OS è ancora molto in divenire, ed è incerto se questa funzionalità sarebbe o non sarebbe adatta per questo ... detto questo, Rust ha abbracciato la distribuzione dei pacchetti anche se Cargo dall'inizio proprio per questo motivo , quindi crea un piccolo pacchetto dedicato a questa funzionalità e condividilo con il mondo tramite casse.io –

+1

È da un po 'che non mi sono fatto molte domande sulle implementazioni di blocco dei file, ma sembra che la libreria Python non sia abbastanza completa. Sembra funzionare principalmente creando file/directory e vedendo se esistono, non fare affidamento sulle funzionalità del sistema operativo. Se si reimplement il blocco dei file, suggerirei di consultare altre risorse per vedere come farlo. – Shepmaster

risposta

6

Per Rust contemporaneo (1,8+) è necessario utilizzare lo fs2 crate. È una libreria multipiattaforma che fornisce alcune funzioni del file system non presenti nella libreria standard, incluso il blocco dei file.

fs2 Le funzioni di blocco file internamente utilizzano flock(2) su UNIX e LockFileEx su Windows.

Esempio:

//! This program tries to lock a file, sleeps for N seconds, and then unlocks the file. 

// cargo-deps: fs2 
extern crate fs2; 

use fs2::FileExt; 
use std::io::Result; 
use std::env::args; 
use std::fs::File; 
use std::time::Duration; 
use std::thread::sleep; 

fn main() { 
    run().unwrap(); 
} 

fn run() -> Result<()> { 
    let sleep_seconds = args().nth(1).and_then(|arg| arg.parse().ok()).unwrap_or(0); 
    let sleep_duration = Duration::from_secs(sleep_seconds); 

    let file = File::open("file.lock")?; 

    println!("{}: Preparing to lock file.", sleep_seconds); 
    file.lock_exclusive()?; // block until this process can lock the file 
    println!("{}: Obtained lock.", sleep_seconds); 

    sleep(sleep_duration); 

    println!("{}: Sleep completed", sleep_seconds); 
    file.unlock()?; 
    println!("{}: Released lock, returning", sleep_seconds); 

    Ok(()) 
} 

Possiamo vedere che i due processi sono in sequenza in attesa sul blocco di file.

$ ./a 4 & ./a 1 
[1] 14894 
4: Preparing to lock file. 
4: Obtained lock. 
1: Preparing to lock file. 
4: Sleep completed 
4: Released lock, returning 
1: Obtained lock. 
1: Sleep completed 
1: Released lock, returning 
[1]+ Done     ./a 4 
2

In Linux è possibile utilizzare nix crate quale wraps unix file lock.

Ecco un esempio:

extern crate nix; 

use std::fs::File; 
use std::os::unix::io::AsRawFd; 
use nix::fcntl::{flock, FlockArg}; 

fn main() { 
    let file = File::open("Cargo.toml").unwrap(); 
    let fd = file.as_raw_fd(); 
    flock(fd, FlockArg::LockExclusive).unwrap(); 

    for rem in (1..20).rev() { 
     println!("Remain: {} sec.", rem); 
     std::thread::sleep(std::time::Duration::from_secs(1)); 
    } 

    drop(file); 
    println!("File unlocked!"); 
} 

Se si tenta di eseguire due istanze, il secondo inizierà il conto alla rovescia solo dopo prima istanza di file sbloccato. Ma un altro programmi possono ignorare questo blocco:

flock (2): funzione inserisce solo serrature di consulenza; dati i permessi adeguati su un file, un processo è libero di ignorare l'uso di flock() ed eseguire I/O sul file.

Problemi correlati