int fcntl(int fildes, int command, ...);
程序改变世界!
分类: LINUX
2015-12-29 09:41:38
原文地址:文件锁机制 作者:zishang-hhg
引用#include
int fcntl(int fildes, int command, ...);
引用int fcntl(int fileds, int command, struct flock *flock_structure)
引用#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
int main()
{
int file_desc;
int byte_count;
char *byte_to_write = "A";
struct flock region_1;
struct flock region_2;
int res;
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write\n", test_file);
exit(EXIT_FAILURE);
}
/* Put some data in the file*/
for( byte_count = 0; byte_count < 100; byte_count++) {
(void)write(file_desc, byte_to_write, 1);
}
/* Set up region 1 with a shared lock, from bytes 10 to 30: */
region_1.l_type = F_RDLCK;
region_1.l_whence = SEEK_SET;
region_1.l_start = 10;
region_1.l_len = 20;
/* Set up region 2 with an exclusive lock, from bytes 40 to 50: */
region_2.l_type = F_WRLCK;
region_2.l_whence = SEEK_SET;
region_2.l_start = 40;
region_2.l_len = 10;
/* Now lock the file */
printf("Process %d locking file\n", getpid());
res = fcntl(file_desc, F_SETLK, ®ion_1);
if (res == -1) fprintf(stderr, "Failed to lock region 1\n");
res = fcntl(file_desc, F_SETLK, ®ion_2);
if (res == -1) fprintf(stderr, "Failed to lock region 2\n");
/* Wait for a while */
sleep(60);
printf("Process %d closing file\n", getpid());
close(file_desc);
exit(EXIT_SUCCESS);
}
引用#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
#define SIZE_TO_TRY 5
void show_lock_info(struct flock *to_show);
int main()
{
int file_desc;
int res;
struct flock region_to_test;
int start_byte;
/* Open a file descriptor */
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write", test_file);
exit(EXIT_FAILURE);
}
for (start_byte = 0; start_byte < 99; start_byte += SIZE_TO_TRY) {
region_to_test.l_type = F_WRLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.l_start = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;
printf("Testing F_WRLCK on region from %d to %d\n",
start_byte, start_byte + SIZE_TO_TRY);
/* Now test lock on the file */
res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if (res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if (region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK returned: \n");
show_lock_info(®ion_to_test);
}
else {
printf("F_WRLCK - Lock would succeed\n");
}
/* Now repeat the test with a shared(read)lock. Set up the region you wish to test again */
region_to_test.l_type = F_RDLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.l_start = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;
printf("Testing F_RDLCK on region from %d to %d\n", start_byte, start_byte + SIZE_TO_TRY);
/* Test the lock on the file again */
res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if (res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if (region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK return: \n");
show_lock_info(®ion_to_test);
}
else {
printf("F_RDLCK - Lock would secceed\n");
}
}
close(file_desc);
exit(EXIT_SUCCESS);
}
void show_lock_info(struct flock *to_show)
{
printf("\tl_type %d, ", to_show->l_type);
printf("l_whence %d, ", to_show->l_whence);
printf("l_start %d, ", (int)to_show->l_start);
printf("l_len %d, ", (int)to_show->l_len);
printf("l_pid %d\n", to_show->l_pid);
}
引用/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
#define F_RDLCK 0 /* Read lock. */
#define F_WRLCK 1 /* Write lock. */
#define F_UNLCK 2 /* Remove lock. */
引用beyes@linux-beyes:~/C> ./lock4.exe
Testing F_WRLCK on region from 0 to 5
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 0 to 5
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 5 to 10
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 5 to 10
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 10 to 15
Lock would fail. F_GETLK returned:
l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 15916
Testing F_RDLCK on region from 10 to 15
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 15 to 20
Lock would fail. F_GETLK returned:
l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 15916
Testing F_RDLCK on region from 15 to 20
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 20 to 25
Lock would fail. F_GETLK returned:
l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 15916
Testing F_RDLCK on region from 20 to 25
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 25 to 30
Lock would fail. F_GETLK returned:
l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 15916
Testing F_RDLCK on region from 25 to 30
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 30 to 35
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 30 to 35
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 35 to 40
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 35 to 40
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 40 to 45
Lock would fail. F_GETLK returned:
l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 15916
Testing F_RDLCK on region from 40 to 45
Lock would fail. F_GETLK return:
l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 15916
Testing F_WRLCK on region from 45 to 50
Lock would fail. F_GETLK returned:
l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 15916
Testing F_RDLCK on region from 45 to 50
Lock would fail. F_GETLK return:
l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 15916
Testing F_WRLCK on region from 50 to 55
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 50 to 55
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 55 to 60
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 55 to 60
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 60 to 65
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 60 to 65
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 65 to 70
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 65 to 70
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 70 to 75
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 70 to 75
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 75 to 80
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 75 to 80
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 80 to 85
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 80 to 85
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 85 to 90
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 85 to 90
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 90 to 95
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 90 to 95
F_RDLCK - Lock would secceed
Testing F_WRLCK on region from 95 to 100
F_WRLCK - Lock would succeed
Testing F_RDLCK on region from 95 to 100
F_RDLCK - Lock would secceed
引用#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
const char buf[10] = {"hello"};
char read_buf[10];
int main()
{
int file_desc;
struct flock region_to_test;
/* Open a file descriptor */
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write", test_file);
exit(EXIT_FAILURE);
}
/* 定位文件到第10个字节处 */
if (lseek(file_desc, 10, SEEK_SET) == -1){
printf("can not locate\n");
return 0;
}
if (write(file_desc, buf, 5) == -1){
printf("Write shared lock area failed\n");
return 0;
}
/* 重新定位到第10个字节处 */
if (lseek(file_desc, 10, SEEK_SET) == -1){
printf("can not locate\n");
return 0;
}
if ( read(file_desc, read_buf, 5) == -1 ) {
printf("can not read the file\n");
return 0;
}
printf("After modify shared lock area and read it out:%s\n", read_buf);
return 0;
}
引用beyes@linux-beyes:~/C> ./lock5.exe
After modify shared lock area and read it out:hello
引用beyes@linux-beyes:~/Desktop> cat /tmp/test_lock
AAAAAAAAAAhelloAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
引用#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
int main()
{
int file_desc;
struct flock region_to_lock;
int res;
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write\n", test_file);
exit(EXIT_FAILURE);
}
region_to_lock.l_type = F_RDLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 10;
region_to_lock.l_len = 5;
printf("Process %d, trying F_RDLCK, region %d to %d\n", getpid(),
(int)region_to_lock.l_start, (int)(region_to_lock.l_start + region_to_lock.l_len));
res = fcntl(file_desc, F_SETLK, ®ion_to_lock);
if (res == -1) {
printf("Process %d - failed to lock region\n", getpid());
} else {
printf("Process %d - obtained lock region\n", getpid());
}
region_to_lock.l_type = F_UNLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 10;
region_to_lock.l_len = 5;
printf("Process %d, trying F_UNLCK, region %d to %d\n", getpid(),
(int)region_to_lock.l_start,
(int)(region_to_lock.l_start + region_to_lock.l_len));
res = fcntl(file_desc, F_SETLK, ®ion_to_lock);
if (res == -1) {
printf("Process %d - failed to unlock region\n", getpid());
} else {
printf("Process %d - unlocked region\n", getpid());
}
region_to_lock.l_type = F_WRLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 16;
region_to_lock.l_len = 5;
printf("Process %d, trying F_WRLCK, region %d to %d\n", getpid(),
(int)region_to_lock.l_start,
(int)(region_to_lock.l_start + region_to_lock.l_len));
res = fcntl(file_desc, F_SETLK, ®ion_to_lock);
if( res == -1 ) {
printf("Process %d - failed to lock region\n", getpid());
} else {
printf("Process %d - obtained lock on region\n", getpid());
}
region_to_lock.l_type = F_RDLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 40;
region_to_lock.l_len = 10;
printf("Process %d, trying F_RDLCK, region %d to %d\n", getpid(),
(int)region_to_lock.l_start,
(int)(region_to_lock.l_start + region_to_lock.l_len));
if (res == -1) {
printf("Process %d - failed to lock region\n", getpid());
} else {
printf("Process %d - obtained lock on region\n", getpid());
}
region_to_lock.l_type = F_WRLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 16;
region_to_lock.l_len = 5;
printf("Process %d, trying F_RDLCK with wait, region %d to %d\n", getpid(),
(int)region_to_lock.l_start,
(int)(region_to_lock.l_start + region_to_lock.l_len));
res = fcntl(file_desc, F_SETLKW, ®ion_to_lock);
if (res == -1) {
printf("Process %d - failed to lock region\n", getpid());
} else {
printf("Process %d - obtained lock on region\n", getpid());
}
printf("Process %d ending\n", getpid());
close(file_desc);
exit(EXIT_SUCCESS);
}
引用beyes@linux-beyes:~/C> ./lock6.exe
Process 19307, trying F_RDLCK, region 10 to 15
Process 19307 - obtained lock region
Process 19307, trying F_UNLCK, region 10 to 15
Process 19307 - unlocked region
Process 19307, trying F_WRLCK, region 16 to 21
Process 19307 - failed to lock region
Process 19307, trying F_RDLCK, region 40 to 50
Process 19307 - failed to lock region
Process 19307, trying F_RDLCK with wait, region 16 to 21
Process 19307 - obtained lock on region
Process 19307 ending
引用#include
int fcntl(int fildes, int cmd);
int fcntl(int fildes, int cmd, long arg);
引用#include
#include
int fcntl(int fd, int cmd, long arg);
引用#include
#include
#include
#include
#include
#include
void my_err(const char *err_string, int line)
{
fprintf(stderr, "line:%d ", line);
perror(err_string);
exit(1);
}
int main()
{
int ret;
int access_mode;
int fd;
if((fd = open("example", O_CREAT|O_TRUNC|O_RDWR, S_IRWXU)) == -1) {
my_err("open", __LINE__);
}
if((ret = fcntl(fd, F_SETFL, O_APPEND)) < 0 ) {
my_err("fcntl", __LINE__);
}
if((ret = fcntl(fd, F_GETFL, 0)) < 0) {
my_err("fcntl", __LINE__);
}
access_mode = ret & O_ACCMODE;
if(access_mode == O_RDONLY) {
printf("example access mode: read-only");
}else if(access_mode == O_WRONLY) {
printf("example access mode: write-only");
}else if(access_mode == O_RDWR) {
printf("example access mode: read+write");
}
if(ret & O_APPEND) {
printf(" ,append");
}
if(ret & O_NONBLOCK) {
printf(" , nonblock");
}
if(ret & O_SYNC) {
printf(" , sync");
}
printf("\n");
return 0;
}
引用beyes@linux-beyes:~/C> ./fcntl_access.exe
example access mode: read+write ,append
引用/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_NDELAY O_NONBLOCK
#define O_SYNC 010000
#define O_FSYNC O_SYNC
#define O_ASYNC 020000