#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;
}
原文地址:http://blog.csdn.net/shallnet/article/details/42473993