View Full Version : [C] Dubbi sul file locking
Ciao a tutti!
Ho dei dubbi riguardo l'uso della funzione fcntl() per effettuare il locking esclusivo sui file (ma penso riguardi anche quello condiviso).
1- Se io ad esempio definisco la struttura di tipo flock così:
struck flock *lock=(struct flock *)malloc(sizeof(struct lock));
lock->l_type=F_WRLCK;
lock->l_whence=SEEK_END;
lock->l_start=0;
lock->l_len=40;
e poi faccio una chiamata a fcntl così:
fcntl(fd,F_SETLKW,lock)
il lock quando verrà liberato? Sulla man page c'è scritto così:
As for F_SETLK, but if conflicting lock is held on the file, then wait for that lock to be released. If a signal is caught while waiting, then the call is interrupted and (after the signal handler has returned) returns immediately.
Da quello che ho capito deve arrivare un segnale dall'altro processo. Ma come fa ad arrivargli? (Premetto che non ho ancora studiato i segnali)
2 - Avendo sempre questa struttura flock, se chiamo la fcntl così:
fcntl(fd,F_GETLK,lock)
Se il lock non esiste su quella porzione che ho specificato nella struct flock, mi riempie il campo l_type scrivendoci F_UNLCK?
3 - Avendo sempre la solita struct, facendo fcntl:
fcntl(fd,F_SETLK,lock)
Se il lock esiste che succede in questo caso?
Grazie :)
ilsensine
28-11-2006, 16:49
Ciao a tutti!
Ho dei dubbi riguardo l'uso della funzione fcntl() per effettuare il locking esclusivo sui file (ma penso riguardi anche quello condiviso).
1- Se io ad esempio definisco la struttura di tipo flock così:
struck flock *lock=(struct flock *)malloc(sizeof(struct lock));
lock->l_type=F_WRLCK;
lock->l_whence=SEEK_END;
lock->l_start=0;
lock->l_len=40;
e poi faccio una chiamata a fcntl così:
fcntl(fd,F_SETLKW,lock)
il lock quando verrà liberato? Sulla man page c'è scritto così:
As for F_SETLK, but if conflicting lock is held on the file, then wait for that lock to be released. If a signal is caught while waiting, then the call is interrupted and (after the signal handler has returned) returns immediately.
Da quello che ho capito deve arrivare un segnale dall'altro processo. Ma come fa ad arrivargli? (Premetto che non ho ancora studiato i segnali)
Quella è la descrizione di F_SETLKW. Se un lock è presente, attende in maniera bloccante; come molte funzioni bloccanti, se viene intercettato un segnale la funzione ritorna con EINTR. Al lock non accade nulla.
Se non intendi gestire i segnali puoi ignorare questo comportamento.
2 - Avendo sempre questa struttura flock, se chiamo la fcntl così:
fcntl(fd,F_GETLK,lock)
Se il lock non esiste su quella porzione che ho specificato nella struct flock, mi riempie il campo l_type scrivendoci F_UNLCK?
Sì.
Nota che F_UNLCK viene ritornato anche se il lock esiste, ma è stato posto dallo stesso processo.
3 - Avendo sempre la solita struct, facendo fcntl:
fcntl(fd,F_SETLK,lock)
Se il lock esiste che succede in questo caso?
Grazie :)
Se tu (il tuo processo) ha già messo quel lock, credo che ne venga messo un altro duplicato (non ho controllato). Se il lock è stato messo da un altro processo, come da manpage la funzione fallisce con EAGAIN o EACCESS, senza bloccare il processo.
Ok, grazie mille ora è chiaro ;)
Un'altra cosa scusa :)
Mettiamo il caso che il processo A apra il file e imposti il lock alla fine del file. Cioè prima mi sposto tramite la lseek alla fine del file, dopodiché imposto un lock a partire da quella posizione per 40 byte. Mettiamo il caso che ora il processo B apra quel file; facendo una lseek ora alla fine del file, qual'è adesso la fine del file? Quella che aveva il processo A prima del lock, oppure è dopo i 40 byte del lock? Inoltre quando setto un lock di n byte su una porzione del file, mi sposta anche il file descriptor n byte più avanti?
Grazie. :)
ilsensine
28-11-2006, 18:07
La semplice imposizione di un lock non altera la dimensione del file, quindi la posizione finale rimane invariata.
Inoltre quando setto un lock di n byte su una porzione del file, mi sposta anche il file descriptor n byte più avanti?
No
Ma per fare un lock alla fine del file sono giuste queste istruzioni?
lock->l_type=F_WRLCK;
lock->l_whence=SEEK_CUR;
lock->l_start=0;
lock->l_len=40;
fcntl(fd,F_SETLK,lock);
Supponendo che il file descriptor sia stato già spostato alla fine del file.
ilsensine
28-11-2006, 18:16
Sì, hai bloccato i prossimi 40 byte dopo la fine del file.
Allora è strano perché quando faccio partire il processo B (con il lock già impostato dal processo A), non mi ritorna -1 ma continua avanti come se non fosse successo niente. Questo è il codice:
#include "acme.h"
int acmebook(int fd){
struct flock *lock=(struct flock *)malloc(sizeof(struct flock));
char *name=(char *)malloc(sizeof(char)*15);
char *surname=(char *)malloc(sizeof(char)*25);
ssize_t nwrite;
size_t len,lenname,lensurname;
lock->l_type=F_WRLCK;
lock->l_whence=SEEK_CUR;
lock->l_start=0;
lock->l_len=40;
if(fcntl(fd,F_SETLK,lock) == -1){
if(lock!=NULL){
free(lock);
lock=NULL;
}
if(name!=NULL){
free(name);
name=NULL;
}
if(surname!=NULL){
free(surname);
surname=NULL;
}
return -1;
}
printf("Insert name and surname: ");
scanf("%s %s", name, surname);
lenname=strlen(name);
lensurname=strlen(surname);
char *passenger=(char *)malloc(sizeof(char)*lenname*lensurname+3);
sprintf(passenger, "%s %s\n", name, surname);
len=strlen(passenger);
if((nwrite = write(fd,passenger,len)) <= 0){
if(lock!=NULL){
free(lock);
lock=NULL;
}
if(name!=NULL){
free(name);
name=NULL;
}
if(surname!=NULL){
free(surname);
surname=NULL;
}
if(passenger!=NULL){
free(passenger);
passenger=NULL;
}
return -1;
}
lock->l_type=F_UNLCK;
if(fcntl(fd,F_SETLK,lock) == -1){
if(lock!=NULL){
free(lock);
lock=NULL;
}
if(name!=NULL){
free(name);
name=NULL;
}
if(surname!=NULL){
free(surname);
surname=NULL;
}
if(passenger!=NULL){
free(passenger);
passenger=NULL;
}
return -1;
}
printf("Thanks Mr./Mrs. %s. Your seat has been reserved.\n", passenger);
if(lock!=NULL){
free(lock);
lock=NULL;
}
if(name!=NULL){
free(name);
name=NULL;
}
if(surname!=NULL){
free(surname);
surname=NULL;
}
if(passenger!=NULL){
free(passenger);
passenger=NULL;
}
return 0;
}
Scusa ho ricontrollato sembra corretto (infatti adesso il lock me lo da). Grazie della disponibilità. :)
ilsensine
28-11-2006, 18:53
Un consiglio casuale: non usare malloc/free per ogni variabile locale che ti capita a tiro :)
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.