linux命令会话被锁定 linux终端锁定( 四 )


所以,如果调用成功,调用程序则可以通过检查flock结构的内容来判断其是否被修改过,来检查锁请求能否被成功执行,而又因为l_pid的值会被设置成拥有锁的进程的标识符,所以大多数情况下,可以通过检查这个字段是否发生变化来判断flock结构是否被修改过 。
使用F_GETLK的fcntl函数调用后会立即返回 。
举个例子来说,例如,有一个flock结构的变量,flock_st,flock_st.l_pid = -1,文件的第10~29个字节已经存在一个读锁,文件的第40~49个字节中已经存在一个写锁,则调用fcntl时,如果用F_GETLK命令 , 来测试在第10~29个字节中是否可以创建一个读锁,因为这个锁可以被创建,所以 , fcntl返回非-1,同时,flock结构的内容也不会改变,flock_st.l_pid = -1 。而如果我们测试第40~49个字节中是否可以创建一个写锁时 , 由于这个区域已经存在一个写锁,测试失败,但是fcntl还是会返回非-1,只是flock结构会被这个区域相关的锁的信息覆盖了,flock_st.l_pid为拥有这个写锁的进程的进程标识符 。
F_SETLK命令,这个命令试图对fildes指向的文件的某个区域加锁或解锁,它的功能根据flock结构的l_type的值而定 。而对于这个命令来说,flock结构的l_pid字段是没有意义的 。如果加锁成功,返回非-1,如果失败,则返回-1 。使用F_SETLK的fcntl函数调用后会立即返回 。
F_SETLKW命令,这个命令与前面的F_SETLK,命令作用相同,但不同的是,它在无法获取锁时 , 即测试不能加锁时,会一直等待直到可以被加锁为止 。
5、例子
看了这么多的说明,可能你已经很乱了 , 就用下面的例子来整清你的思想吧 。
源文件名为filelock2.c,用于创建数据文件,并将文件区域加锁,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打开一个文件描述符 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); } //给文件添加100个‘A’字符的数据 for(byte_count = 0; byte_count100; ++byte_count) { write(file_desc, byte_to_write, 1); } //在文件的第10~29字节设置读锁(共享锁) region_1.l_type = F_RDLCK; region_1.l_whence = SEEK_SET; region_1.l_start = 10; region_1.l_len = 20; //在文件的40~49字节设置写锁(独占锁) region_2.l_type = F_WRLCK; region_2.l_whence = SEEK_SET; region_2.l_start = 40; region_2.l_len = 10; printf("Process %d locking file ", getpid()); //锁定文件 res = fcntl(file_desc, F_SETLK, ?ion_1); if(res == -1) { fprintf(stderr, "Failed to lock region 1 "); } res = fcntl(file_desc, F_SETLK, ?ion_2); if(res == -1) { fprintf(stderr, "Failed to lock region 2 "); } //让程序休眠一分钟,用于测试 sleep(60); printf("Process %d closing file ", getpid()); close(file_desc); exit(EXIT_SUCCESS); }
下面的源文件filelock3.c用于测试上一个文件设置的锁,测试可否对两个区域都加上一个读锁,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h int main() { const char *test_file = "test_lock.txt"; int file_desc = -1; int byte_count = 0; char *byte_to_write = "A"; struct flock region_1; struct flock region_2; int res = 0; //打开数据文件 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); } //设置区域1的锁类型 struct flock region_test1; region_test1.l_type = F_RDLCK; region_test1.l_whence = SEEK_SET; region_test1.l_start = 10; region_test1.l_len = 20; region_test1.l_pid = -1; //设置区域2的锁类型 struct flock region_test2; region_test2.l_type = F_RDLCK; region_test2.l_whence = SEEK_SET; region_test2.l_start = 40; region_test2.l_len = 10; region_test2.l_pid = -1; //

推荐阅读