flock与fcntl所实现的文件锁一样,既能够用在多进程上,也能用在多线程上,而且使用起来比fcntl的实现方式更方便,只是使用这个函数时,需要注意一些小细节。
代码演示:
ret = fork();
if (ret > 0)
{
fd = open("./hello1", O_RDWR|O_CREAT|O_TRUNC|O_APPEND, 0664);
if (fd == -1) print_err("./hello1", __LINE__, errno);
while(1)
{
flock(fd, LOCK_SH);
write(fd, "hello ", 6);
write(fd, "world\n", 6);
flock(fd, LOCK_UN);
}
}
else if (ret == 0)
{
fd = open("./hello1", O_RDWR|O_CREAT|O_TRUNC|O_APPEND, 0664);
if (fd == -1) print_err("./hello1", __LINE__, errno);
while(1)
{
flock(fd, LOCK_SH);
write(fd, "hello ", 6);
write(fd, "world\n", 6);
flock(fd, LOCK_UN);
}
}
flock用于多进程时,各进程必须独立open打开文件,对于非亲缘进程来说,不用说打开文件时肯定是各自独立调用open打开的。
需要你注意的是亲缘进程(父子进程),子进程不能使用从父进程继承而来的文件描述符,父子进程flock时必须使用独自open返回的文件描述符。
这一点与fcntl实现的文件锁不一样,父子进程可以使用各自open返回的文件描述符加锁,但是同时子进程也可以使用从父进程继承而来的文件描述符加锁。
用于多线程
代码演示:
void *pth_fun(void *pth_arg)
{
int fd;
fd = open("./hello", O_RDWR|O_CREAT|O_TRUNC, 0664);
if (fd == -1) print_err("./hello", __LINE__, errno);
while(1)
{
flock(fd, LOCK_EX);
write(fd, "hello ", 6);
write(fd, "world\n", 6);
flock(fd, LOCK_UN);
}
return NULL;
}
int main(int argc, char *argv[])
{
int fd = -1;
int ret = -1;
pthread_t tid;
fd = open("./hello", O_RDWR|O_CREAT|O_TRUNC, 0664);
if (fd == -1) print_err("./hello", __LINE__, errno);
ret = pthread_create(&tid, NULL, pth_fun, NULL);
if (ret == -1) print_err("pthread_create fail", __LINE__, ret);
while(1)
{
flock(fd, LOCK_EX);
write(fd, "hello ", 6);
write(fd, "world\n", 6);
flock(fd, LOCK_UN);
}
return 0;
}
用于多线程时与用于多进程一样,各线程必须使用各自open所返回的文件描述符才能加锁。