<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux內(nèi)核中的文件描述符(四)--fd的分配--get_unused_fd

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

          作者: 時(shí)間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          Kernel version:2.6.14

          CPU architecture:ARM920T

          本文引用地址:http://www.ex-cimer.com/article/201611/320000.htm

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

          linux內(nèi)核中主要有兩個(gè)函數(shù)涉及到文件描述符的分配: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;//獲得當(dāng)前進(jìn)程的打開文件列表files
          4. intfd,error;
          5. structfdtable*fdt;
          6. error=-EMFILE;
          7. spin_lock(&files->file_lock);
          8. repeat:
          9. fdt=files_fdtable(files);//獲得文件描述符位圖結(jié)構(gòu)
          10. fd=find_next_zero_bit(fdt->open_fds->fds_bits,
          11. fdt->max_fdset,
          12. fdt->next_fd);
          13. //find_next_zero_bit函數(shù)在文件描述符位圖fds_bits中從next_fd位開始搜索下一個(gè)(包括next_fd)為0的位,也就是分配一個(gè)文教描述符
          14. /*
          15. *N.B.Forclonetaskssharingafilesstructure,thistest
          16. *willlimitthetotalnumberoffilesthatcanbeopened.
          17. */
          18. if(fd>=current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//檢查是否超過當(dāng)前進(jìn)程限定的最大可打開文件數(shù)
          19. gotoout;
          20. /*Doweneedtoexpandthefdarrayorfdset?*/
          21. error=expand_files(files,fd);//根據(jù)需要擴(kuò)展fd,稍后我們會詳細(xì)介紹該函數(shù)。返回值<0,錯(cuò)誤;返回值>0,擴(kuò)展后再次進(jìn)行fd的分配
          22. if(error<0)
          23. gotoout;
          24. if(error){
          25. /*
          26. *Ifweneededtoexpandthefsarraywe
          27. *mighthaveblocked-tryagain.
          28. */
          29. error=-EMFILE;
          30. gotorepeat;//之前進(jìn)行了擴(kuò)展操作,重新進(jìn)行一次空閑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是一個(gè)進(jìn)程可以打開的最大文件數(shù)量。我們首先來看RLIMIT_NOFILE,該值定義如下:

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

          在signal結(jié)構(gòu)中,rlim是struct rlimit類型的數(shù)組,

          [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;//當(dāng)前值
          3. unsignedlongrlim_max;//最大值
          4. };

          這些值時(shí)是在哪設(shè)定的呢?我們應(yīng)該知道,linux內(nèi)核通過fork創(chuàng)建進(jìn)程,第一個(gè)進(jìn)程是靜態(tài)定義的。因此,如果進(jìn)程創(chuàng)建后沒有修改這些值,那么這些和第一個(gè)進(jìn)程中的值應(yīng)該是一樣的。下面是第一個(gè)進(jìn)程的task_struct結(jié)構(gòu),僅列出部分?jǐn)?shù)據(jù)。

          [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,也就是說進(jìn)程最多可以打開1024個(gè)文件。


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();