UNIXでのファイル制御--fcntl()


ファイル制御関数fcntl--file control LIBRARY Standard C Library(libc,-lc)SYNOPSIS#include;         int fcntl(int fd, int cmd, ...); [説明]Fcntl()は(ファイル)記述子に対して制御を提供する.パラメータfdは、パラメータcmdによって操作する(以下に説明する)記述子である.cmdの値に対して、fcntlが3番目のパラメータint arg fcntl関数を受け入れることができるのは5つの機能がある:1.既存の記述子(cmd=F_DUPFD)をコピーする.2.ファイル記述子タグ(cmd=F_GETFDまたはF_SETFD)を取得/設定.3.ファイル状態フラグ(cmd=F_GETFLまたはF_SETFL)を取得/設定.4.非同期I/O所有権(cmd=F_GETOWNまたはF_SETOWN)を取得/設定.5.記録ロック(cmd=F_GETLK、F_SETLKまたはF_SETLKW)を取得/設定.cmd値:F_DUPFDは、以下に説明する(ファイル)を返す記述子:oの最小のarg以上の使用可能な記述子oと元のオペレータのような対象の参照oオブジェクトがファイル(file)であれば、新しい記述子を返します.この記述子はargと同じオフセット量(offset)oと同じアクセスモード(読み取り、書き込み、または読み取り/書き込み)oと同じファイル状態フラグ(例えば、2つのファイル記述子が同じ状態フラグを共有する)を共有するo新しいファイル記述子と結合されたclose-on-execフラグは、クロスアクセスexecve(2)のシステム呼び出しF_に設定されるGETFDは、ファイル記述子fdと結合したclose-on-execフラグを取得し、FD_CLOEXEC.値とFD_を返すとCLOEXECと演算結果が0の場合、ファイルはクロスアクセスexec()を保持し、そうでない場合はexecで実行するとファイルは閉じられます(argは無視されます)F_SETFDはclose-on-execフラグを設定します.このフラグはパラメータargのFD_CLOEXEC位決定.                    F_GETFLは、fdのファイル状態フラグを取得し、以下の説明のように(argは無視される)F_SETFLはarg記述子状態フラグに設定され、変更可能ないくつかのフラグは:O_APPEND, O_NONBLOCK,O_SYNCとO_ASYNC.                       F_GETOWNは、現在SIGIOまたはSIGURG信号を受信しているプロセスidまたはプロセスグループidを取得し、プロセスグループidは負の値(argは無視)F_に戻るSETOWNはSIGIOとSIGURG信号を受信するプロセスidまたはプロセスグループidを設定し、プロセスグループidは負のargを提供することによって説明され、そうでなければargはプロセスidコマンドワード(cmd)F_とみなされるGETFLとF_SETFLのフラグは以下の通りである:O_NONBLOCK非ブロックI/O;read(2)呼び出しに読み取り可能なデータがない場合、またはwrite(2)操作がブロックされる場合、readまたはwrite呼び出し戻り-1およびEAGAINエラーO_APPENDはwrite操作のたびにファイルの大きい末尾に追加することを強制し、open(2)のO_に相当する.APPENDフラグO_DIRECTはreadingとwritingのキャッシュの影響を最小化または除去する.システムはあなたの読み取りや書き込みのデータをキャッシュすることを避けようとします.キャッシュを回避することができなければ、キャッシュされたデータによる影響を最小限に抑えることができる.このマークが不十分であれば、パフォーマンスが大幅に低下します.
 O_ASYNC                    
I/Oが利用可能な場合、SIGIO信号をプロセスグループに送信することを許可し、例えば、データが読める場合
ファイル記述子フラグまたはファイルステータスフラグを変更する場合は、まず現在のフラグ値を取得し、変更するには、最後に新しいフラグ値を設定する必要があります.F_を実行するだけではいけませんSETFDまたはF_SETFLコマンドは、以前に設定したフラグビットをオフにします.fcntlの戻り値はコマンドに関係します.エラーが発生した場合、すべてのコマンドは-1を返し、成功した場合は別の値を返します.次の3つのコマンドには、特定の戻り値があります.F_DUPFD,F_GETFD,F_GETFLおよびF_GETOWN.最初に戻る
のファイル記述子、2番目は対応するフラグを返し、最後は正のプロセスIDまたは負のプロセスグループIDを返します.
次に、fdを制御する例を示す
#include
#include
#include
#include
using namespace std;
int main(int argc,char* argv[])
{
int fd,var;
// fd=open("new",O_RDWR);
if (argc!=2)
{
perror("--");
cout
}
if((var=fcntl(atoi(argv[1]), F_GETFL, 0))
}
/**        (O_RDONLY,O_WRONLY,  O_RDWR)    1 。(         0、1 2,   
   。      —             。)          O_ACCMODE       ,             。
****/
switch(var & O_ACCMODE)
{
case O_RDONLY : cout
break;
case O_WRONLY : cout
break;
case O_RDWR : cout
break;
default : break;
}
if (val & O_APPEND)
cout
if (val & O_NONBLOCK)
cout
cout
exit(0);
}

ファイルのロック解除を実現
複数のユーザが1つのファイルを共同で使用し、操作する場合、Linuxは通常、共有されたリソースが競合する状態を回避するためにファイルに鍵をかける方法を採用する.
ファイルロックには、推奨ロックと強制ロックが含まれます.
推奨ロックでは、各ロックファイルのプロセスがロックが存在するかどうかを確認し、既存のロックを尊重する必要があります.一般的に、カーネルとシステムは推奨ロックを使用しません.
強制ロックはカーネルによって実行されるロックであり、1つのファイルがロックされて書き込み操作されると、カーネルは他のファイルの読み書き操作を阻止します.強制ロックの使用はパフォーマンスに大きな影響を及ぼし、読み書き操作のたびにロックが存在するかどうかを確認する必要があります.
Linuxでは、ファイルのロックを実現する関数としてlockとfcntlがあり、flockはファイルに推奨ロックを適用するために使用され、fcntlは推奨ロックを適用するだけでなく、強制ロックを適用することもでき、ファイルのある記録に対してロック、すなわち記録ロックを行うこともできる.
記録ロックは、読み出しロックと書き込みロックに分けられる.
読み取りロックは共有ロックとも呼ばれ、複数のプロセスがファイルの同じ部分で読み取りロックを確立することができます.
書き込みロックは反発ロックとも呼ばれ、ファイルの一部に書き込みロックを確立するプロセスはいつでも1つしかありません.
ファイルの同じ部分に読み取りロックと書き込みロックを同時に確立することはできません.
(2)fcntl関数フォーマット
Fcntl関数構文の要点:
必要なヘッダファイル:#include
                     #include
                     #include
関数プロトタイプ:int fcntl(int fd,cmd,struct flock*lock)
関数入力値:fd:ファイル記述子
                     Cmd:F_DUPFD:ファイル記述子のコピー
F_GETFD:fdのclose-on-execフラグを取得し、フラグが設定されていない場合、ファイルはexec関数を経ても開いたままになります.
F_SETFD:パラメータargのFD_CLOEXEC位決定.
F_GETFL:Open設定フラグを取得
F_SETFL:open設定変更フラグ
F_GETFK:lockの説明に従って、ファイルロックをかけるかどうかを決定する
F_SETFK:lock記述のファイルロックを設定する
F_SETLKW:F_ですSETLKのブロックバージョン(コマンド名のWはウエイトを表す).他のロックがある場合は、プロセススリープを呼び出します.信号をキャッチするとスリープが切れます
F_GETOWN:SIGIOおよびSIGURG信号を受信するプロセス番号またはプロセスグループ番号を取得する
F_SETOWN:プロセス番号またはプロセスグループ番号の設定
ロック:構成はflockで、記録ロックの具体的な状態を設定する
関数の戻り値:成功:0
-1:エラー
ロックの構成は以下の通りです.
Struct flock{
Short l_type;
Off_t l_start;
Short l_whence;
Off_t l_len;
Pid_t l_pid;
}
ロック構造変数の値:
L_type:F_RDLCK:リードロック(共有ロック)
              F_WRLCK:書き込みロック(反発ロック)
              F_UNLCK:ロック解除
L_stat:相対変位量(バイト)
L_whence:相対変位量の始点(同lseekのwhence):SEEK_SET:現在位置はファイルの先頭、新しい位置はオフセットの大きさ
                                    SEEK_CUR:現在位置はファイルポインタ位置、新しい位置は現在位置にオフセット量を加える
                                    SEEK_END:現在位置はファイルの最後、新しい位置はファイルのサイズにオフセットサイズを加える
L_len:ロック領域長
例:
Lock_set  :
void lock_set(int fd,int type)
{
       struct flock lock;
       lock.l_whence=SEEK_SET;//  lock   
       lock.l_start=0;
       lock.l_len=0;
       while(1)
       {
              lock.l_type=type;
/*     type         */
              if((fcntl(fd,F_SETLK,&lock))==0)
              {
                     if(lock.l_type==F_RDLCK)
                            printf("read lock set by %d
",getpid()); else if(lock.l_type=F_WRLCK) printf("write lock set by %d
",getpid()); else if(lock.l_type=F_UNLCK) printf("release lock set by %d
",getpid()); return; } /* */ fcntl(fd,F_GETLK,&lock); /* */ if(lock.l_type!=F_UNLCK) { /* */ if(lock.l_type==F_RDLCK) printf("read lock already set by %d
",lock.l_pid()); /* */ else if(lock.l_type=F_WRLCK) printf("write already lock set by %d
", lock.l_pid ()); getchar(); } } } /*fcntl_write.c */ #include<unistd.h> #include<sys/file.h> #include<sys/types.h> #include<sys/stat.h> #include<stdio.h> #include<stdlib.h> int main(void) { int fd; fd=open("hello",O_RDWR|O_CREAT,0666); if(fd<0) { perror("open"); exit(1); } lock_set(fd,F_WRLCK); getchar(); lock_set(fd,F_UNLCK); getchar(); close(fd); exit(0); }