经过上一节的介绍,我们晓得在linux中进行C语言开发时,多进程同时写数据到同一个文件,假若不留神处理,写入的数据可能会混乱。这主要是由于每位进程打开文件时,都有独立的文件表记录当前文件偏斜量的诱因。
这么,在一个进程中多次打开同一个文件同时写入数据,也可能出现数据混乱吗?答案是肯定的,还记得第10节的这张图吗?
虽然在一个进程中多次调用open函数打开同一个文件,系统也会为每次调用分配一个文件表记录当前文件偏斜量。这时linux 文件描述符,情况就和上一节介绍的多进程同时写数据到同一个文件的情况类似了,还是十分可能出现数据混乱的。
请看下边的代码:
#include#include#include#include#include#include#includeintmain(){char*filename="test.bin";intfd,fd2;fd=open(filename,O_WRONLY|O_CREAT);fd2=open(filename,O_WRONLY|O_CREAT);charbuf1[20];charbuf2[30];memset(buf1,1,sizeof(buf1));memset(buf2,2,sizeof(buf2));write(fd,buf1,sizeof(buf1));write(fd2,buf2,sizeof(buf2));close(fd);close(fd2);return0;}
代码的逻辑很简单,就是在main函数里打开test.bin文件两次,并分别往上面写入20个字节的1,和30个字节的2。编译执行之,得到如下结果:
容易看出,fd写入的数据被fd2写入的数据覆盖了,这与我们上面的剖析是一致的。
实际开发中,还是十分有可能须要打开同一个文件多次的,例如多线程项目中,每位线程都须要操作test.bin文件,这时使用多个fd愈加便捷。C语言的dup和dup2函数
好在,C语言提供的dup和dup2函数,就特别适宜解决多个fd写数据到同一个文件的需求。dup和dup2都可拿来复制一个现存的文件描述符,使两个文件描述符指向同一个文件表。
在linux中输入man命令即可查询dup函数的描述:
现今使用dup函数更改里面的代码,复制一份fd传递给fd2:
...fd=open(filename,O_WRONLY|O_CREAT);fd2=dup(fd);charbuf1[20];...
更改之后,编译执行,发觉两次写入的数据都保留了。
这是由于fd2是由dup函数复制fd而至,它俩共享同一个文件表,也即共享同一个当前文件偏斜量。上面两节介绍过,fd调用write写入数据后,会将当前文件偏斜量更新,这时fd2也就接着fd写入的数据尾部写入数据了。
再瞧瞧里面的代码,尽管fd2是复制fd而至的,并且仍需调用close函数关掉之。所以假如只执行第26行代码,linux内核只会将test.bin文件的打开计数减一linux 文件描述符,并没有真正关掉文件。因而,第27行的close(fd2);是必需的。
这也能看出多线程操作同一个文件,使用dup的用处了。某个线程使用完文件后,直接close即可(这能使代码有更好的逻辑完整性linux mint,可阅读性更强),而无需担忧其他线程。
dup函数复制fd时,总是返回尽可能小的未使用fd号。dup2函数与dup函数的功能时类似的,惟一的区别是dup2函数有两个参数,执行成功后,会返回第二个参数传递的fd值。
多进程打开同一个文件时,能借助dup函数防止数据衰弱吗?
既然dup函数还能复制fdlinux运维面试题,这么,上一节出现的问题也能用dup函数的特点解决吗?这个问题就留给读者思索了。经过这两节的讨论,相信读者也有能力编撰相应的C语言代码验证自己的看法。
这儿有一点小提示:进程间一般并不共享显存,而进程打开文件时,文件表信息保留在自己的显存空间里的。
欢迎在评论区一起讨论,指责。文章都是手打原创,每晚最扼要的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以见到最新更新和之前的文章哦。
,