经过调试,以下函数好像有点问题
例如有两个线程A,B
A调用open打开文件,并且运行
这一行,运行结果失败,清楚d中的内容,这时候,线程B也执行open,判断到ref_count==0(被线程A清零),所以获取到d, 但是在运行下句之前
,切换回线程A,A执行fd_put(ref_count已经被线程B执行fd_new()置1), 这时候,ref_count被A清零了,然后执行线程B的时候,线程B就会执行
获取到空的指针d,最后导致在线程B在执行fd_put的时候出错。
你要多线程操作同一个fd?这个是非线程安全的,同时非常不建议采用这样的方式,这样还会涉及到底层文件系统的多任务是否安全(基本上来说是不安全的)。
如果你需要在上层应用多线程方式操作fd,请保证在进行文件系统调用操作前,进行应用层的加锁。
没有多线程去操作同一个fd,是多线程open文件,而且open的不是同一个文件,是线程A open文件的时候失败,把一个fd_table释放了(即调用了 dfs_file_open,dfs_file_open清零了fd_table)之后,然后线程B获取到线程A未完全释放的fd_table(因为A后面还没有调用fd_put),线程B获取后,又切换回线程A,线程A这时候才调用fd_put。具体流程如下图:
[attach]0[/attach]
图好小,看不清。
fd_new()出来后,ref_count = 1;
dfs_file_open前有一次fd_get,ref_count = 2;
dfs_file_open出错后,会连续两次fd_put释放ref_count:
fd_put -> ref_count = 1;
fd_put -> ref_count = 0;
当ref_count = 0时,把fd清零,归还到fd table里。
fd会有锁,是在fd_new/fd_get/fd_put里面。所以只有当ref_count = 0以后,才会放到fd table里。要从fd table里获得一个新的fd,也需要在加锁的状态下,检查ref_count 是否是0才能够获得一个新的fd。
不好意思,图小了,我重新上传pdf文件。
正常情况是这样子的,但是在dfs_file_open里面有这样一段:
即在dfs_file_open里面ref_count=0了,所以在没有进行fd_put的时候,别人是可以获取到fd_table的。