linux中lockf的例子,linux文件锁定

linux下文件锁定有两种:一种是以原子操作方式创建锁文件;另一种是允许锁定文件的一部分,从而独享对这一部分内容的访问。

1、锁文件

许多应用程序只需要能够针对某个资源创建一个锁文件,然后其他程序通过检查这个文件来判断它们是否被允许访问这个资源。创建锁文件使用fcntl.h头文件(楼主机器上位于/usr/include下)定义的open系统调用,并带上O_CREAT和O_EXCL标志。这样就以原子操作完成两项工作:确定文件不存在,然后    创建

#include #include #include #include #include int main()

{

int file_desc;

int save_errno;

file_desc = open("/tmp/LCK.test", O_RDWR | O_CREAT | O_EXCL, 0444);

if (file_desc == -1) {

save_errno = errno;

printf("Open failed with error %d\n", save_errno);

}

else {

printf("Open succeeded\n");

}

exit(EXIT_SUCCESS);

}

不过在第二次运行以上程序的时候,会提示错误:open failed with error 17(文件已存在,错误码在/usr/include/asm-generic/error-base.h),如果想让程序再次执行成功,就必须删除那个锁文件。在c语言调用中,我们可以使用unlink函数(定义于/usr/include/unistd.h)。另外,以上的代码也不是很合理的,只有open没有close,正常情况下,应该加上以下两行:

(void)close(file_desc);

(void)unlink( "/tmp/LCK.test");

关于unlink。unlink原型如下:

#include int unlink (__const char *__name)

函数功能:删除目录项,并将由__name所引用文件的链接

计数减1,当链接计数为0时,文件被删除。

关于unlink的使用,可以参考《unix环境高级编程》第17章,17.3.2唯一链接,在listen前,先unlink以防文件已经存在,accept后再unlink,防止下次调用处问题。曾经楼主在ACE的unix域套接字ACE_LSOCK上遇到address in use,其实就是锁文件已存在没有删除的问题。

2、区域锁定

区域锁定出现,是因为锁文件方式并不适用于访问大型的共享文件。如果一个大文件,由一个程序写入数据,但却由不同的程序同时对这个文件进行更新。处理程序不能等待记录程序结束,所以需要一些协调方法来提供对同一个文件的并发访问。linux提供了2种方法来实现:一是fcntl系统调用和lockf调用。

一个使用fcntl锁定文件的例子如下:

#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;

/* 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\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);

}

/* setup region 1, a shared lock, from bytes 10 -> 30 */

region_1.l_type = F_RDLCK;

region_1.l_whence = SEEK_SET;

region_1.l_start = 10;

region_1.l_len = 20;

/* setup region 2, an exclusive lock, from bytes 40 -> 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");

/* and wait for a while */

sleep(60);

printf("Process %d closing file\n", getpid());

close(file_desc);

exit(EXIT_SUCCESS);

}

程序首先创建一个文件,然后以读写方式打开,添加一些数据。接着在文件中设置2个区域,第一个是0-30,用读(共享)锁;第二个是40-50,用写(独占) 锁,然后调用fcntl来锁定这2个区域。

fcntl参数提供了3个命令选项

F_GETLK、F_SETLK、F_SETLKW,l_type提供的选项有F_RDLCK、F_UNLCK、F_WRLCK,分别为读锁,解锁,写锁

测试锁的程序如下:

#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) {

/* set up the region we wish to test */

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 the 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 we wish to test */

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);

/* now test the 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_RDLCK - Lock would succeed\n");

}

} /* for */

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);

}

(以上大部分内容来自《linux程序设计》)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: lockf函数是Linux系统的一个文件锁定函数,它可以用来锁定一个文件的某个区域,以防止其他进程对该区域进行读写操作。lockf函数的使用非常简单,只需要指定文件描述符、锁定方式、锁定起始位置和锁定长度即可。在使用lockf函数时,需要注意避免死锁和竞争条件等问题。 ### 回答2: lockf()函数是linux系统提供的文件锁定函数,可以通过锁定文件进行线程之间的同步和互斥控制。 lockf()函数可以实现两种类型的文件锁定:共享锁和排它锁。 共享锁允许多个进程同时对同一个文件进行读操作,但是任何一个进程想要对该文件进行写操作的时候,必须先解除该文件的共享锁定。 排它锁可以保证在任何时刻只能有一个进程对该文件进行读写操作,其他进程必须等待该进程解除该文件锁定才能对该文件进行操作。 lockf()函数可以通过指定锁定的范围来实现对文件的部分或全部锁定。通过使用lockf()函数,进程可以将某个范围内的文件锁定在内存,从而防止其他进程对该文件进行修改。 lockf()函数还可以对已经被锁定文件进行修改或者删除。如果一个进程希望对一个已被锁定文件进行修改或删除,那么该进程需要先解除该文件锁定,否则将无法对该文件进行任何操作。 总之,lockf()函数是linux系统提供的一个非常重要的文件锁定函数,可以实现线程之间的同步和互斥控制。在编写多线程程序时,使用lockf()函数可以有效地避免数据竞争和死锁等问题,提高程序的稳定性和可靠性。 ### 回答3: lockf函数是Linux系统用于在文件实现锁操作的函数,可以用于控制文件的读或写等操作,避免多个进程同时对同一个文件进行读写操作而导致数据混乱或错误的情况。其主要作用是提供了一种可靠的文件锁定方法,为多进程访问同一文件提供了保障。 lockf函数的基本用法为: int lockf(int fd, int cmd, off_t len); 其,fd参数是所要锁定文件描述符,cmd参数是锁定操作的指令,可以是F_LOCK、F_TLOCK、F_ULOCK和F_TEST等,len参数是所要锁定的字节数。 具体来说,F_LOCK指令是指锁定整个文件,只有当整个文件锁定成功后,进程才可以对该文件进行读写操作;F_TLOCK指令是指试图锁定整个文件,如果出现锁冲突,则不会阻塞进程,而是返回EAGAIN错误;F_ULOCK指令是指解除文件锁定;F_TEST指令是指测试文件锁定情况,如果文件已经被锁定,则返回-1,否则返回0。 在使用lockf函数时需要注意以下几点: 1、lockf函数并不是实现进程间通信的机制,只是用来对多个进程对文件进行访问的控制; 2、使用lockf时需要同步一致地运用操作锁定与解除锁定的指令,以避免死锁的情况; 3、lockf锁定文件的范围不应该超出文件的范围; 4、使用lockf时,如果出现了系统断等问题,需要及时处理,以防止文件无法被正常解锁。 总之,lockf函数是一种实现进程对文件并发访问控制的有效工具,在Linux系统具有广泛的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值