ファイル ロックは、特定の時間に 1 つのプロセスだけがファイルにアクセスできるようにするメカニズムです。ファイル ロック メカニズムを使用することで、多くのプロセスがより安全な方法で 1 つのファイルを読み書きできるようになります。
この記事では、さまざまな種類の Linux ファイル ロックを調査し、サンプル プログラムを使用してそれらの違いを理解します。
次の例を使用して、ファイル ロックが必要な理由を理解します。
このような問題を回避するために、「シリアル化」を確実にするためにロックが使用されます。
Linux ファイルのロックには、次の 2 種類があります。
<オール>1.アドバイザリ ロック
アドバイザリ ロックには、参加プロセスからの協力が必要です。プロセス「A」が WRITE ロックを取得し、ファイルへの書き込みを開始したとします。プロセス「B」は、ロックを取得しようとせずに、ファイルを開いて書き込みを行うことができます。ここで、プロセス「B」は非協調プロセスです。プロセス「B」がロックを取得しようとすると、このプロセスが「シリアライゼーション」を保証するために協力していることを意味します。
アドバイザリ ロックは、参加しているプロセスが協調的である場合にのみ機能します。アドバイザリ ロックは、「強制されていない」ロックとも呼ばれます。
2.強制ロック
強制ロックは、参加プロセスからの協力を必要としません。強制ロックにより、カーネルはすべてのオープン、読み取り、および書き込みをチェックして、呼び出しプロセスが特定のファイルのロックに違反していないことを確認します。強制ロックの詳細については、kernal.org を参照してください
Linux で強制ロックを有効にするには、ファイル システム レベルと個々のファイルで有効にする必要があります。従うべき手順は次のとおりです:
<オール>Linux ファイル ロックの例
これがどのように機能するかを理解するには、次の file_lock.c プログラムを作成してください:
#include <stdio.h> #include <fcntl.h> int main(int argc, char **argv) { if (argc > 1) { int fd = open(argv[1], O_WRONLY); if(fd == -1) { printf("Unable to open the file\n"); exit(1); } static struct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; lock.l_pid = getpid(); int ret = fcntl(fd, F_SETLKW, &lock); printf("Return value of fcntl:%d\n",ret); if(ret==0) { while (1) { scanf("%c", NULL); } } } }
gcc を使用してプログラムをコンパイルします。
# cc -o file_lock file_lock.c
以下に示すように、mount コマンドを使用して「mand」オプションを指定してルート ファイルシステムを再マウントします。これにより、ファイル システム レベルで強制ロックが有効になります。
注:以下のコマンドを実行するには、root になる必要があります。
# mount -oremount,mand /
実行可能ファイル (file_lock) があるディレクトリに「advisory.txt」と「mandatory.txt」という名前の 2 つのファイルを作成します。次のように、Set-Group-ID を有効にし、「mandatory.txt」の Group-Execute-Bit を無効にします
# touch advisory.txt # touch mandatory.txt # chmod g+s,g-x mandatory.txt
テスト アドバイザリ ロック: 次に、「advisory.txt」を引数としてサンプル プログラムを実行します。
# ./file_lock advisory.txt
プログラムはユーザーからの入力を待ちます。別の端末またはコンソールから、次のことを試してください
# ls >>advisory.txt
上記の例では、ls コマンドはその出力を advisory.txt ファイルに書き込みます。書き込みロックを取得しても、他のプロセス (非協力) がファイルに書き込むことができます。これは「アドバイザリ」ロックと呼ばれます。
強制ロックのテスト: 再度「mandatory.txt」を引数にしてサンプルプログラムを実行してください。
# ./file_lock mandatory.txt
別の端末またはコンソールから、次のことを試してください:
# ls >>mandatory.txt
上記の例では、ls コマンドはロックが解除されるのを待ってから、出力を manual.txt ファイルに書き込みます。これは依然として非協調的なプロセスですが、ロックは強制ロックを使用して実現されます。