當有多個進程要訪問同一個文件的時候,為了防止多進程訪問導致的不一致,我們就要考慮進程間的同步問題了。
舉例說明:在嵌入式編程中經常會遇到寫配置文件的問題,這個時候由於多進程操作就需要跟配置文件加寫鎖操作。
fcntl是一個非常強大的函數,在這里我們可以使用它來給文件的某一個部分上鎖。先來看一下它的聲明:
int fcntl(int filedes, int cmd, ... /* struct flock *flockptr */ );
這是一個擁有可變參數的函數聲明,filedes自然是要操作的文件描述符,對與記錄鎖相關的操作,cmd只能是F_GETLK, F_SETLK, 或者 F_SETLKW,而第三個參數則必須是一個指向flock結構體的指針,來看一下該結構體的內部結構:
1 struct flock { 2 short l_type;/*F_RDLCK, F_WRLCK, or F_UNLCK */
3 off_t l_start;/*offset in bytes, relative to l_whence */
4 short l_whence;/*SEEK_SET, SEEK_CUR, or SEEK_END */
5 off_t l_len;/*length, in bytes; 0 means lock to EOF */
6 pid_t l_pid;/*returned with F_GETLK */
7 };
第一個成員是加鎖的類型:只讀鎖,讀寫鎖,或是解鎖。l_start和l_whence用來指明加鎖部分的開始位置,l_len是加鎖的長度,l_pid是加鎖進程的進程id。比如說,我們現在需要把一個文件的前三個字節加讀鎖,則該結構體的l_type=F_RDLCK, l_start=0, l_whence=SEEK_SET, l_len=3,l_pid不需要指定,然后調用fcntl函數時,cmd參數使用F_SETLK.
leveldb用法:
1 int LockOrUnlock(int fd, bool lock) { 2 errno = 0; 3 struct ::flock file_lock_info; 4 std::memset(&file_lock_info, 0, sizeof(file_lock_info)); 5 file_lock_info.l_type = (lock ? F_WRLCK : F_UNLCK); 6 file_lock_info.l_whence = SEEK_SET; 7 file_lock_info.l_start = 0; 8 file_lock_info.l_len = 0; // Lock/unlock entire file.
9 return ::fcntl(fd, F_SETLK, &file_lock_info); 10 }
