Heim  >  Artikel  >  System-Tutorial  >  Eine Technik für die Linux-Systemprogrammierung: Verwendung von fcntl() zum Implementieren von Lese-/Schreibsperren

Eine Technik für die Linux-Systemprogrammierung: Verwendung von fcntl() zum Implementieren von Lese-/Schreibsperren

WBOY
WBOYnach vorne
2024-02-13 16:03:24871Durchsuche

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.

Linux 系统编程的一种技巧:使用 fcntl() 实现读写锁

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. fcntl

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.

2.Beispiel für eine Lese-/Schreibsperre

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:

3. Führen Sie zuerst eine Lesesperre und dann eine Schreibsperre durch. Die Ergebnisse sind wie folgt:

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

4. Wenn Sie zuerst die Schreibsperre und dann die Lesesperre ausführen, sind die Ergebnisse wie folgt:

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:lxlinux.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen