Linux互斥与同步应用(六):文件锁
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ );函数对所打开的文件描述符fd,根据不同的cmd命令执行不同的操作,针对文件锁的命令有如下:
struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* Starting offset for lock */ off_t l_len; /* Number of bytes to lock */ pid_t l_pid; /* PID of process blocking our lock (F_GETLK only) */ ... };
/** * \brief acquire, release or test for the existence of record locks * \details if a conficling is held on the file, then return -1. * * \param fd - file descriptor * \param locktype - lock type: F_RDLCK, F_WRLCK, F_UNLCK. * * \return 0 is success, < 0 is failed. */ static int sln_filelock_set(int fd, short locktype) { struct flock lock; lock.l_type = locktype; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = getpid(); if (fcntl(fd, F_SETLK, &lock) < 0) { fprintf(stderr, "fcntl: %s\n", strerror(errno)); return -1; } return 0; } /** * \brief acquire, release or test for the existence of record locks * \details if a conficling is held on the file, then wait for that * lock to be release * * \param fd - file descriptor * \param locktype - lock type: F_RDLCK, F_WRLCK, F_UNLCK. * * \return 0 is success, < 0 is failed. */ int sln_filelock_wait_set(int fd, short locktype) { struct flock lock; lock.l_type = locktype; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = getpid(); if (fcntl(fd, F_SETLKW, &lock) < 0) { fprintf(stderr, "fcntl: %s\n", strerror(errno)); return -1; } return 0; } int sln_file_wrlock(int fd) { return sln_filelock_set(fd, F_WRLCK); } int sln_file_rdlock(int fd) { return sln_filelock_set(fd, F_RDLCK); } int sln_file_wait_wrlock(int fd) { return sln_filelock_wait_set(fd, F_WRLCK); } int sln_file_wait_rdlock(int fd) { return sln_filelock_wait_set(fd, F_RDLCK); } int sln_file_unlock(int fd) { return sln_filelock_set(fd, F_UNLCK); } /** * \brief test for the existence of record locks on the file * \details none * * \param fd - file descriptor * \param locktype - lock type: F_RDLCK, F_WRLCK. * * \return 0 is success, < 0 is failed. */ static int sln_filelock_test(int fd, short locktype) { struct flock lock; lock.l_type = locktype; lock.l_whence = 0; lock.l_start = 0; lock.l_len = 0; lock.l_pid = 0; if (fcntl(fd, F_GETLK, &lock) < 0) { fprintf(stderr, "fcntl: %s\n", strerror(errno)); return -1; } if (lock.l_type != F_UNLCK) { //file is locked if (F_WRLCK == lock.l_type) { printf("write lock hold by process <%d>, lock_type: %d\n", lock.l_pid, lock.l_type); } else if (F_RDLCK == lock.l_type) { printf("read lock hold by process <%d>, lock_type: %d\n", lock.l_pid, lock.l_type); } return lock.l_pid; //return the pid of process holding that lock } else { printf("Unlock, lock type: %d\n", lock.l_type); return 0; } } int sln_file_wrlock_test(int fd) { return sln_filelock_test(fd, F_WRLCK); } int sln_file_rdlock_test(int fd) { return sln_filelock_test(fd, F_RDLCK); }
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include "filelock.h" int main(int argc, const char *argv[]) { int fd; if (argc != 2) { fprintf(stderr, "Usage: %s <write_str>\n", argv[0]); return -1; } fd = open("filelock.txt", O_RDWR | O_CREAT, 0644); if (fd < 0) { fprintf(stderr, "open: %s\n", strerror(errno)); return -1; } if (sln_file_wait_wrlock(fd) < 0) { printf("lock write failed!\n"); close(fd); return -1; } printf("process <%d> holding write lock ok!\n", getpid()); write(fd, argv[1], strlen(argv[1])); sleep(10); sln_file_unlock(fd); printf("release lock!\n"); close(fd); return 0; }
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include "filelock.h" int main(int argc, const char *argv[]) { int fd; char buf[1024]; fd = open("filelock.txt", O_RDONLY | O_CREAT, 0644); if (fd < 0) { fprintf(stderr, "open: %s\n", strerror(errno)); return -1; } if (sln_file_wait_rdlock(fd) < 0) { printf("lock read failed!\n"); close(fd); return -1; } printf("process <%d> holding read lock ok!\n", getpid()); sleep(10); read(fd, buf, sizeof(buf)); printf("read buf: %s\n", buf); sln_file_unlock(fd); printf("release lock!\n"); close(fd); return 0; }
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include "filelock.h" int main(int argc, const char *argv[]) { int fd, pid; fd = open("filelock.txt", O_RDWR | O_CREAT, 0644); if (fd < 0) { fprintf(stderr, "open: %s\n", strerror(errno)); return -1; } pid = sln_file_wrlock_test(fd); if (pid > 0) { printf("write locked!\n"); } else { printf("write unlock!\n"); } pid = sln_file_rdlock_test(fd); if (pid > 0) { printf("read locked!\n"); } else { printf("read unlock!\n"); } close(fd); return 0; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。