linux open file的时候到底做了什么呢?
如图:
这样多线程对文件读写,可见,也是需要对文件进行同步保护的。
但是这和内存变量的同步似乎有些不太一样,也就是用mutex好像不能互斥文件open之后的读写吧?
看来需要锁这个东西,它的机制和内存锁mutex应该是一样的吧,猜测的!希望后面能看到例子。
代码保存一下:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char **argv) { int file_id1=open("test.txt",O_RDWR); if(file_id1<0) printf("open file_id_1 is error\n"); printf("file_id_1 is %d\n",file_id1); int file_id2=open("test.txt",O_RDWR); if(file_id2<0) printf("open file_id_2 is error\n"); printf("file_id_2 is %d\n",file_id2); // int jump_length=lseek(file_id1,10,SEEK_SET); //sleep(60); char buffer1[128]={0}; char buffer2[128]={0}; int length1= read(file_id1,buffer1,10); printf("length1 %d\n",length1); printf("content1 %s\n",buffer1); char * write_string="######"; write(file_id1,write_string,strlen(write_string)); int length2= read(file_id1,buffer2,20); printf("length2 %d\n",length2); printf("content2 %s\n",buffer2); return 0; }
2. 文件的锁。文件的锁从进程的视角来锁定某个文件。
函数int lockf(int fie_id, int function,int length);
file_id 为要锁定文件的文件标示符,function可以取以下参数
F_ULOCK 为一个先前锁定的区域解锁
F_LOCK 锁定一个区域
F_TLOCK 测试并锁定一个区域
F_TEST 测试一个区域是否已经上锁。
这个锁的机制和内存的锁定机制是极其类似的,所以我们直接上代码:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char **argv) { int file_id1=open("test.txt",O_RDWR); if(file_id1<0) printf("open file_id_1 is error\n"); printf("file_id_1 is %d\n",file_id1); int file_id2=open("test.txt",O_RDWR); if(file_id2<0) printf("open file_id_2 is error\n"); printf("file_id_2 is %d\n",file_id2); // int jump_length=lseek(file_id1,10,SEEK_SET); //sleep(60); char buffer1[128]={0}; char buffer2[128]={0}; lockf(file_id1,F_LOCK,10L); int length1= read(file_id1,buffer1,10); printf("length1 %d\n",length1); printf("content1 %s\n",buffer1); sleep(20); /* char * write_string="######"; write(file_id1,write_string,strlen(write_string)); int length2= read(file_id1,buffer2,20); printf("length2 %d\n",length2); printf("content2 %s\n",buffer2); */ return 0; }
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char **argv) { int file_id1=open("test.txt",O_RDWR); if(file_id1<0) printf("open file_id_1 is error\n"); printf("file_id_1 is %d\n",file_id1); int file_id2=open("test.txt",O_RDWR); if(file_id2<0) printf("open file_id_2 is error\n"); printf("file_id_2 is %d\n",file_id2); int jump_length=lseek(file_id1,10,SEEK_SET); //sleep(60); char buffer1[128]={0}; char buffer2[128]={0}; lockf(file_id1,F_LOCK,10L); int length1= read(file_id1,buffer1,10); printf("length1 %d\n",length1); printf("content1 %s\n",buffer1); sleep(20); /* char * write_string="######"; write(file_id1,write_string,strlen(write_string)); int length2= read(file_id1,buffer2,20); printf("length2 %d\n",length2); printf("content2 %s\n",buffer2); */ return 0; }
先运行fork.c,fork.c会锁定test.txt文件,如果锁到和fork2进程操作的test.txt的同一个位置,那么会阻塞fork2进程。
效果图:
这里有个问题是,文件是可以被多个进程访问的,但是如果我们的进程如果不用lockf的话是可以访问到,读写任何文件的,但是其实比如有些程序是不想让其他文件在自己修改的同时,被其他程序修改的,这时,我们可以利用F_TEST参数来测试
这个文件是否被其他进程lock,如果这个文件被其他进程lock,则函数 int result=flock(file_id, F_TEST, 0L); 会返回-1,如果没有锁定的位置相交,则返回0;
这时我们可以适度加锁,来避免和别的进程来争抢资源。