新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux內核中的文件描述符(四)--fd的分配--get_unused_fd

        linux內核中的文件描述符(四)--fd的分配--get_unused_fd

        作者: 時間:2016-11-22 來源:網絡 收藏
        Kernel version:2.6.14

        CPU architecture:ARM920T

        本文引用地址:http://www.104case.com/article/201611/320000.htm

        Author:ce123(http://blog.csdn.net/ce123)

        linux內核中主要有兩個函數涉及到文件描述符的分配:get_unused_fd和locate_fd。本文主要講解get_unused_fd,將會在下一篇文章中介紹locate_fd。首先給出get_unused_fd的定義(fs/open.c):

        [plain]view plaincopy
        print?
        1. intget_unused_fd(void)
        2. {
        3. structfiles_struct*files=current->files;//獲得當前進程的打開文件列表files
        4. intfd,error;
        5. structfdtable*fdt;
        6. error=-EMFILE;
        7. spin_lock(&files->file_lock);
        8. repeat:
        9. fdt=files_fdtable(files);//獲得文件描述符位圖結構
        10. fd=find_next_zero_bit(fdt->open_fds->fds_bits,
        11. fdt->max_fdset,
        12. fdt->next_fd);
        13. //find_next_zero_bit函數在文件描述符位圖fds_bits中從next_fd位開始搜索下一個(包括next_fd)為0的位,也就是分配一個文教描述符
        14. /*
        15. *N.B.Forclonetaskssharingafilesstructure,thistest
        16. *willlimitthetotalnumberoffilesthatcanbeopened.
        17. */
        18. if(fd>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//檢查是否超過當前進程限定的最大可打開文件數
        19. gotoout;
        20. /*Doweneedtoexpandthefdarrayorfdset?*/
        21. error=expand_files(files,fd);//根據需要擴展fd,稍后我們會詳細介紹該函數。返回值<0,錯誤;返回值>0,擴展后再次進行fd的分配
        22. if(error<0)
        23. gotoout;
        24. if(error){
        25. /*
        26. *Ifweneededtoexpandthefsarraywe
        27. *mighthaveblocked-tryagain.
        28. */
        29. error=-EMFILE;
        30. gotorepeat;//之前進行了擴展操作,重新進行一次空閑fd的分配
        31. }
        32. FD_SET(fd,fdt->open_fds);//在open_fds的位圖上置位
        33. FD_CLR(fd,fdt->close_on_exec);
        34. fdt->next_fd=fd+1;//next_fd加1
        35. #if1
        36. /*Sanitycheck*/
        37. if(fdt->fd[fd]!=NULL){
        38. printk(KERN_WARNING"get_unused_fd:slot%dnotNULL!n",fd);
        39. fdt->fd[fd]=NULL;
        40. }
        41. #endif
        42. error=fd;
        43. out:
        44. spin_unlock(&files->file_lock);
        45. returnerror;
        46. }

        current->signal->rlim[RLIMIT_NOFILE].rlim_cur是一個進程可以打開的最大文件數量。我們首先來看RLIMIT_NOFILE,該值定義如下:

        [plain]view plaincopy
        print?
        1. #defineRLIMIT_NOFILE7/*maxnumberofopenfiles*/

        在signal結構中,rlim是struct rlimit類型的數組,

        [plain]view plaincopy
        print?
        1. structsignal_struct{
        2. ...
        3. structrlimitrlim[RLIM_NLIMITS];
        4. ...
        5. };
        struct rlimit定義如下
        [plain]view plaincopy
        print?
        1. structrlimit{
        2. unsignedlongrlim_cur;//當前值
        3. unsignedlongrlim_max;//最大值
        4. };

        這些值時是在哪設定的呢?我們應該知道,linux內核通過fork創建進程,第一個進程是靜態定義的。因此,如果進程創建后沒有修改這些值,那么這些和第一個進程中的值應該是一樣的。下面是第一個進程的task_struct結構,僅列出部分數據。

        [plain]view plaincopy
        print?
        1. linux/arch/arm/kernel/init_task.c
        2. structtask_structinit_task=INIT_TASK(init_task);
        3. #defineINIT_TASK(tsk)
        4. {
        5. ...
        6. .signal=&init_signals,
        7. ...
        8. }
        init_signals的定義如下:

        [plain]view plaincopy
        print?
        1. #defineINIT_SIGNALS(sig){
        2. .count=ATOMIC_INIT(1),
        3. .wait_chldexit=__WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),
        4. .shared_pending={
        5. .list=LIST_HEAD_INIT(sig.shared_pending.list),
        6. .signal={{0}}},
        7. .posix_timers=LIST_HEAD_INIT(sig.posix_timers),
        8. .cpu_timers=INIT_CPU_TIMERS(sig.cpu_timers),
        9. .rlim=INIT_RLIMITS,
        10. }
        11. includeasm-genericresource.h
        12. #defineINIT_RLIMITS
        13. {
        14. [RLIMIT_CPU]={RLIM_INFINITY,RLIM_INFINITY},
        15. [RLIMIT_FSIZE]={RLIM_INFINITY,RLIM_INFINITY},
        16. [RLIMIT_DATA]={RLIM_INFINITY,RLIM_INFINITY},
        17. [RLIMIT_STACK]={_STK_LIM,_STK_LIM_MAX},
        18. [RLIMIT_CORE]={0,RLIM_INFINITY},
        19. [RLIMIT_RSS]={RLIM_INFINITY,RLIM_INFINITY},
        20. [RLIMIT_NPROC]={0,0},
        21. [RLIMIT_NOFILE]={INR_OPEN,INR_OPEN},
        22. [RLIMIT_MEMLOCK]={MLOCK_LIMIT,MLOCK_LIMIT},
        23. [RLIMIT_AS]={RLIM_INFINITY,RLIM_INFINITY},
        24. [RLIMIT_LOCKS]={RLIM_INFINITY,RLIM_INFINITY},
        25. [RLIMIT_SIGPENDING]={0,0},
        26. [RLIMIT_MSGQUEUE]={MQ_BYTES_MAX,MQ_BYTES_MAX},
        27. [RLIMIT_NICE]={0,0},
        28. [RLIMIT_RTPRIO]={0,0},
        29. }
        30. #defineNR_OPEN(1024*1024)/*Absoluteupperlimitonfdnum*/
        31. #defineINR_OPEN1024/*Initialsettingfornfilerlimits*/
        從上面的代碼我們可以看到rlim_cur = 1024,也就是說進程最多可以打開1024個文件。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 昌乐县| 龙口市| 宁化县| 田阳县| 郧西县| 南通市| 蓬莱市| 阿勒泰市| 曲阜市| 吴忠市| 南通市| 清河县| 三都| 镇江市| 仪征市| 林芝县| 故城县| 钦州市| 连南| 张家口市| 旬邑县| 林芝县| 泾阳县| 裕民县| 黄大仙区| 磐石市| 海阳市| 潜山县| 兴海县| 同德县| 西安市| 北海市| 仪征市| 固阳县| 祥云县| 扎兰屯市| 讷河市| 彰化市| 齐河县| 北安市| 甘泉县|