Die Lese-/Schreibsperre ist ein häufig verwendeter Synchronisationsmechanismus, der es mehreren Prozessen oder Threads ermöglicht, gleichzeitige Lesevorgänge oder sich gegenseitig ausschließende Schreibvorgänge für dieselbe Ressource auszuführen und so die Effizienz und Sicherheit des Systems zu verbessern. In der Linux-Systemprogrammierung gibt es viele Möglichkeiten, Lese-/Schreibsperren zu implementieren, z. B. die Verwendung der Pthread-Bibliothek, die Verwendung von Dateisperren usw. In diesem Artikel werden Ihnen eine Methode zur Verwendung des Systemaufrufs fcntl() zum Implementieren von Lese-/Schreibsperren sowie deren Prinzipien, Verwendung, Vor- und Nachteile vorgestellt, damit Sie diese Technik in der Linux-Systemprogrammierung besser verwenden und verstehen können.
Wenn mehrere Prozesse Lese- und Schreibzugriff auf dieselbe Datei haben, muss die Datei gesperrt werden, um die Integrität der Daten sicherzustellen. Dateien können über die Funktion fcntl() gesperrt und entsperrt werden.
1.1. Funktionsbeschreibung: Dateieigenschaften basierend auf Dateideskriptoren bearbeiten.
1.2. Verwendung:
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fd: Dateideskriptor.
cmd: Betriebsbefehl.
arg: Vom Befehl verwendete Parameter Ob der arg-Parameter erforderlich ist, hängt vom cmd-Befehl ab.
Sperre: Sperrinformationen.
Erstellen Sie zwei neue Dateien. Der Quellcode wird in 2.1 und 2.2 unten angezeigt.
2.1. Lesesperre zur Datei hinzufügen
#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; }
/*
Hinweis:
1. Lock_1 in fcntl(fd,F_GETLK,&lock_1) muss initialisiert werden und lock_1.l_type muss auf die entsprechende Sperre gesetzt werden, um festzustellen, ob die Sperre erfolgreich gesperrt werden kann und was der Grund für den Fehler ist.
2. Beim GETLK erkennt fcntl zunächst, ob eine Sperre vorhanden ist, die diese Sperre verhindern kann. Wenn vorhanden, überschreibt es die Informationen der Flockstruktur (lock_1). Wenn nicht, setzen Sie den Typ von lock_1.l_type auf F_UNLCK.
*/
Bei Schreibsperren (exklusive F_WRLCK-Sperren) kann nur ein Prozess eine exklusive Sperre für einen bestimmten Bereich der Datei genießen.
Bei Lesesperren (F_RDLCK-Gemeinschaftssperren) können viele verschiedene Prozesse gleichzeitig gemeinsame Sperren für denselben Bereich der Datei halten. Um eine gemeinsame Sperre aufrechtzuerhalten, muss die Datei zum Lesen oder Lesen/Schreiben geöffnet werden. Solange ein Prozess eine gemeinsame Sperre besitzt, kann kein anderer Prozess eine exklusive Sperre erhalten.
Kompilieren und separat ausführen:
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
Schreibsperre erfolgreich gesetzt
Es ist ersichtlich, dass, wenn die Datei mit einer Lesesperre belegt ist, keine Schreibsperre (exklusive Sperre) hinzugefügt werden kann
liu@ubuntu:~/learn/lrn_linux$ ./writelock.out
Prozess-PID: 16349
Schreibsperre erfolgreich gesetzt
liu@ubuntu:~/learn/lrn_linux$ ./readlock.out
Prozess-PID: 16350
fcntl fail : Resource temporarily unavailable
Die Sperrung ist also erfolgreich.
Durch diesen Artikel sollten Sie ein grundlegendes Verständnis der Methode zur Verwendung von fcntl() zum Implementieren von Lese-/Schreibsperren in der Linux-Systemprogrammierung haben und deren Prinzipien, Verwendung sowie Vor- und Nachteile kennen. Sie sollten auch den Zweck und die Auswirkungen der Verwendung von fcntl() zur Implementierung von Lese-/Schreibsperren verstehen und wissen, wie Sie fcntl() in der Linux-Systemprogrammierung richtig verwenden und konfigurieren. Wir empfehlen Ihnen, fcntl() zu verwenden, um Ihre Ziele in Szenarien zu erreichen, in denen Sie Lese-/Schreibsperren implementieren müssen. Gleichzeitig erinnern wir Sie auch daran, bei der Verwendung von fcntl() auf einige potenzielle Probleme und Herausforderungen zu achten, wie z. B. Kompatibilität, Portabilität, Leistung usw. Ich hoffe, dieser Artikel kann Ihnen dabei helfen, die Linux-Systemprogrammierung besser zu nutzen und die Fähigkeiten und Vorteile von fcntl() unter Linux zu beherrschen.
Das obige ist der detaillierte Inhalt vonEine Technik für die Linux-Systemprogrammierung: Verwendung von fcntl() zum Implementieren von Lese-/Schreibsperren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!