参考文章:http://blog.jobbole.com/104331/
本文对flock、lockf函数的表现做验证。
这里对lockf函数在线程中的使用做了验证
void* thread( void *arg)
{
int fd1;
int ret;
fd1 = open(file,O_RDWR);
ret = lockf(fd1,F_LOCK, 0);
printf("child get lock, fd: %d, ret: %d\n", fd1, ret);
return NULL;
}
if (strcmp(argv[1], "1")==0) {
int fd;
pthread_t th;
int ret;
void *thread_ret ;
fd = open(file,O_RDWR);
ret = lockf(fd,F_LOCK, 0);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
ret = pthread_create( &th, NULL, thread, NULL );
if( ret != 0 ){
printf( "Create thread error!\n" );
return -1;
}
printf( "This is the main process.\n" );
pthread_join( th, &thread_ret );
}
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 1
parent get lock, fd: 3, ret: 0
This is the main process.
child get lock, fd: 4, ret: 0
上面的例子,在线程中使用了lockf函数但从结果看出,在父子线程中均可以对文件加锁,后面我们可以得出结论,文件锁在线程中是失效的,仅可以在进程中使用文件锁,线程访问同一文件可以使用互斥锁或读写锁的方式进行限制。
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
ret = lockf(fd,F_LOCK, 0);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = lockf(fd,F_LOCK, 0);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 2
parent get lock, fd: 3, ret: 0
parent exit
第2个例子我们可以看出打开一次文件分别在父子进程中使用lockf对文件加锁,只能有一个进程获得锁,另一个进程将处于阻塞状态。
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
ret = flock(fd,LOCK_EX);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = flock(fd,LOCK_EX);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 3
parent get lock, fd: 3, ret: 0
parent exit
chile get lock, fd: 3, ret: 0
chile exit
第3个例子我们可以看出打开一次文件分别在父子进程中使用flock对文件加锁,则父子进程均可以获得锁。
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
int fdc = open(file, O_RDWR);
ret = flock(fdc,LOCK_EX);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = flock(fd,LOCK_EX);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 4
parent get lock, fd: 3, ret: 0
parent exit
第4个例子我们可以看出分别在父子进程中打开文件,使用flock对文件加锁,则只能有一个进程获得锁。
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
ret1 = flock(fd,LOCK_EX);
printf("ret1 = %d\n", ret1);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 5
ret = 0
ret1 = 0
第5个例子,只有一个进程,打开一次文件,重复使用flock加锁,都可以获得锁。
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
int fd1 = open(file,O_RDWR);
ret1 = flock(fd1,LOCK_EX);
printf("ret1 = %d\n", ret1);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 6
ret = 0
第6个例子,只有一个进程,打开两次文件,两次使用flock对不同的fd加锁,后请求加锁的将阻塞。
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = lockf(fd, F_LOCK, 0);
printf("ret = %d\n", ret);
ret1 = lockf(fd,F_LOCK, 0);
printf("ret1 = %d\n", ret1);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 7
ret = 0
ret1 = 0
第7个例子,只有一个进程,打开一次文件,重复使用lock加锁,都可以获得锁。
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
int fd1 = open(file, O_RDWR);
ret1 = flock(fd1,LOCK_EX);
printf("ret1 = %d\n", ret1);
zhao@bruce:~/workspace/linuxc_learn/file_learn$ ./filelock 8
ret = 0
第6个例子,只有一个进程,打开两次文件,两次使用lockf对不同的fd加锁,后请求加锁的将阻塞。
下面附上源码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
char file[20] = "file_size";
void* thread( void *arg)
{
int fd1;
int ret;
fd1 = open(file,O_RDWR);
ret = lockf(fd1,F_LOCK, 0);
printf("child get lock, fd: %d, ret: %d\n", fd1, ret);
return NULL;
}
int main( int argc, char *argv[] )
{
//lockf in thread
if (argc !=2) {
return 0;
}
if (strcmp(argv[1], "1")==0) {
int fd;
pthread_t th;
int ret;
void *thread_ret ;
fd = open(file,O_RDWR);
ret = lockf(fd,F_LOCK, 0);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
ret = pthread_create( &th, NULL, thread, NULL );
if( ret != 0 ){
printf( "Create thread error!\n" );
return -1;
}
printf( "This is the main process.\n" );
pthread_join( th, &thread_ret );
}
//locf in fork
else if(strcmp(argv[1], "2")==0) {
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
ret = lockf(fd,F_LOCK, 0);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = lockf(fd,F_LOCK, 0);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
}
//flock in fork
else if(strcmp(argv[1],"3")==0) {
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
ret = flock(fd,LOCK_EX);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = flock(fd,LOCK_EX);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
}
else if(strcmp(argv[1],"4")==0) {
int ret;
int pid;
int sta;
int fd = open(file,O_RDWR);
if ((pid = fork()) == 0){
int fdc = open(file, O_RDWR);
ret = flock(fdc,LOCK_EX);
printf("chile get lock, fd: %d, ret: %d\n",fd, ret);
printf("chile exit\n");
exit(0);
}
ret = flock(fd,LOCK_EX);
printf("parent get lock, fd: %d, ret: %d\n", fd, ret);
printf("parent exit\n");
wait(&sta);
}
//dont't fork
else if(strcmp(argv[1],"5")==0) {
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
ret1 = flock(fd,LOCK_EX);
printf("ret1 = %d\n", ret1);
}
else if(strcmp(argv[1],"6")==0) {
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
int fd1 = open(file,O_RDWR);
ret1 = flock(fd1,LOCK_EX);
printf("ret1 = %d\n", ret1);
}
else if(strcmp(argv[1],"7")==0) {
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = lockf(fd, F_LOCK, 0);
printf("ret = %d\n", ret);
ret1 = lockf(fd,F_LOCK, 0);
printf("ret1 = %d\n", ret1);
}
else if(strcmp(argv[1],"8")==0) {
int ret;
int ret1;
int fd = open(file,O_RDWR);
ret = flock(fd, LOCK_EX);
printf("ret = %d\n", ret);
int fd1 = open(file, O_RDWR);
ret1 = flock(fd1,LOCK_EX);
printf("ret1 = %d\n", ret1);
}
return 0;
}