Le verrouillage en lecture-écriture est un mécanisme de synchronisation couramment utilisé, qui permet à plusieurs processus ou threads d'effectuer des opérations de lecture simultanées ou des opérations d'écriture mutuellement exclusives sur la même ressource, améliorant ainsi l'efficacité et la sécurité du système. Dans la programmation système Linux, il existe de nombreuses façons d'implémenter des verrous en lecture-écriture, comme l'utilisation de la bibliothèque pthread, l'utilisation de verrous de fichiers, etc. Cet article vous présentera une méthode d'utilisation de l'appel système fcntl() pour implémenter des verrous en lecture-écriture, ainsi que ses principes, son utilisation, ses avantages et ses inconvénients, afin que vous puissiez mieux utiliser et comprendre cette technique dans la programmation système Linux.
Lorsque plusieurs processus accèdent en lecture et en écriture au même fichier, afin de garantir l'intégrité des données, le fichier doit être verrouillé. Les fichiers peuvent être verrouillés et déverrouillés via la fonction fcntl().
1.1. Description de la fonction : Manipuler les caractéristiques des fichiers en fonction des descripteurs de fichiers.
1.2. Utilisation :
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fd : descripteur de fichier.
cmd : commande d'opération.
arg : paramètres utilisés par la commande. La nécessité ou non du paramètre arg dépend de la commande cmd.
lock : informations de verrouillage.
Créez deux nouveaux fichiers, le code source est affiché en 2.1 et 2.2 ci-dessous.
2.1. Ajouter un verrou de lecture au fichier
#include \#include \#include \#include \#include int main(int argc, const char * argv [ ]) { int fd = open("test.c", O_RDONLY); if (fd == -1) { perror("open failed:"); return -1; } struct stat sta; fstat(fd,&sta); struct flock lock; lock.l_len = sta.st_size; lock.l_pid = getpid(); lock.l_start = 0; lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; printf("进程pid: %d\n",lock.l_pid); if(fcntl(fd,F_SETLK,&lock) == -1) { perror("fcntl fail "); return -1; } else { printf("add read lock success!\n"); } sleep(10); close(fd); return 0; } 2.2.给文件加写锁 \#include \#include \#include \#include \#include int main(int argc, const char * argv [ ]) { int fd = open("test.c", O_WRONLY); if (fd == -1) { perror("open failed:"); return -1; } struct stat sta; fstat(fd,&sta); struct flock lock; lock.l_len = sta.st_size; lock.l_pid = getpid(); lock.l_start = 0; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; printf("进程pid: %d\n",lock.l_pid); while(fcntl(fd,F_SETLK,&lock) == -1 ) { perror("fcntl:"); sleep(1); struct flock lock_1; lock_1 = lock; lock_1.l_type = F_WRLCK; // fcntl(fd,F_GETLK,&lock_1);//获取文件锁状态,及加锁(lock_1.l_type)能否成功 switch(lock_1.l_type) { case F_RDLCK: printf("检测到读锁 pid = %d \n",lock_1.l_pid); break; case F_WRLCK: printf("检测到写锁 pid = %d \n",lock_1.l_pid); break; case F_UNLCK: printf("检测到已解锁.pid = %d \n",lock_1.l_pid); } } printf("写锁设置成功\n"); getchar(); close(fd); return 0; }
/*
Remarque :
1. Lock_1 dans fcntl(fd,F_GETLK,&lock_1) doit être initialisé et lock_1.l_type doit être défini sur le verrou correspondant pour déterminer si le verrou peut être verrouillé avec succès et la raison de l'échec.
2. Lorsque GETLK, fcntl détecte d'abord s'il existe un verrou qui peut empêcher ce verrouillage, s'il existe, il écrase les informations de la structure flock (lock_1). Sinon, définissez le type de lock_1.l_type sur F_UNLCK.
*/
Pour les verrous en écriture (verrous exclusifs F_WRLCK), un seul processus peut bénéficier d'un verrou exclusif sur une zone spécifique du fichier.
Pour les verrous en lecture (verrous partagés F_RDLCK), de nombreux processus différents peuvent détenir des verrous partagés sur la même zone du fichier en même temps. Afin de détenir un verrou partagé, le fichier doit être ouvert en lecture ou en lecture/écriture. Tant qu'un processus possède un verrou partagé, aucun autre processus ne peut obtenir un verrou exclusif.
Compilez et exécutez séparément :
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out 进程pid: 16458 add read lock success! liu@ubuntu:~/learn/lrn_linux$ ./writelock.out 进程pid: 16459 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到读锁 pid = 16458 fcntl:: Resource temporarily unavailable 检测到已解锁.pid = 16459
Écrire le verrouillage défini avec succès
On constate que lorsque le fichier est occupé par un verrou en lecture, un verrou en écriture (verrou exclusif) ne peut pas être ajouté
liu@ubuntu:~/learn/lrn_linux$ ./writelock.out
Pid de processus : 16349
Écrire le verrouillage défini avec succès
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out
Pid de processus : 16350
fcntl fail : Resource temporarily unavailable
Le verrouillage est donc réussi.
Grâce à cet article, vous devez avoir une compréhension de base de la méthode d'utilisation de fcntl() pour implémenter des verrous en lecture-écriture dans la programmation système Linux, et connaître ses principes, son utilisation, ses avantages et ses inconvénients. Vous devez également comprendre le but et l'impact de l'utilisation de fcntl() pour implémenter des verrous en lecture-écriture, et comment utiliser et configurer correctement fcntl() dans la programmation système Linux. Nous vous recommandons d'utiliser fcntl() pour atteindre vos objectifs dans les scénarios où vous devez implémenter des verrous en lecture-écriture. Dans le même temps, nous vous rappelons également de prêter attention à certains problèmes et défis potentiels lors de l'utilisation de fcntl(), tels que la compatibilité, la portabilité, les performances, etc. J'espère que cet article pourra vous aider à mieux utiliser la programmation système Linux et vous permettre de maîtriser les compétences et les avantages de fcntl() sous Linux.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!