精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux系統下fd分配的方法

系統 Linux
在windows上面單個fd_set中容納的socket handle個數不能超過FD_SETSIZE(在win32 winsock2.h里其定義為64,以VS2010版本為準),并且fd_set結構使用一個數組來容納這些socket handle的,每次FD_SET宏都是向這個數組中放入一個socket handle

[[119930]]

最近幾天在公司里寫網絡通訊的代碼比較多,自然就會涉及到IO事件監測方法的問題。我驚奇的發現select輪訓的方法在那里居然還大行其道。我告訴他們現在無論在Linux系統下,還是windows系統下,select都應該被廢棄不用了,其原因是在兩個平臺上select的系統調用都有一個可以說是致命的坑。

在windows上面單個fd_set中容納的socket handle個數不能超過FD_SETSIZE(在win32 winsock2.h里其定義為64,以VS2010版本為準),并且fd_set結構使用一個數組來容納這些socket handle的,每次FD_SET宏都是向這個數組中放入一個socket handle,并且此過程中是限定了不能超過FD_SETSIZE,具體請自己查看winsock2.h中FD_SET宏的定義。

此處的問題是

若本身fd_set中的socket handle已經達到FD_SETSIZE個,那么后續的FD_SET操作實際上是沒有效果的,對應socket handle的IO事件將被遺漏!!!

而在Linux系統下面,該問題其實也是處在fd_set的結構和FD_SET宏上。此時fd_set結構是使用bit位序列來記錄每一個待檢測IO事件的fd。記錄的方式稍微復雜,如下

/usr/include/sys/select.h中

  1. typedef long int __fd_mask;  
  2. #define __NFDBITS    (8 * sizeof (__fd_mask))  
  3. #define    __FDELT(d)    ((d) / __NFDBITS)  
  4.  
  5. #define    __FDMASK(d)    ((__fd_mask) 1 << ((d) % __NFDBITS))  
  6.  
  7. typedef struct  
  8.   {  
  9.     /* XPG4.2 requires this member name.  Otherwise avoid the name  
  10.        from the global namespace.  */  
  11. #ifdef __USE_XOPEN  
  12.     __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];  
  13. # define __FDS_BITS(set) ((set)->fds_bits)  
  14. #else  
  15.     __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];  
  16. # define __FDS_BITS(set) ((set)->__fds_bits)  
  17. #endif  
  18.   } fd_set;  
  19.  
  20. #define    FD_SET(fd, fdsetp)    __FD_SET (fd, fdsetp) 

/usr/include/bits/select.h中

  1. 1 # define __FD_SET(d, set)    (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) 

可以看出,在上面的過程,實際上每個bit在fd_set的bit序列中的位置對應于fd的值。而fd_set結構中bit位個數是__FD_SETSIZE定義的,__FD_SETSIZE在/usr/include/bits/typesize.h(包含關系如下sys/socket.h -> bits/types.h -> bits/typesizes.h)中被定義為1024。

現在的問題是,當fd>=1024時,FD_SET宏實際上會引起內存寫越界。而實際上在man select中對已也有明確的說明,如下

NOTES

 

An fd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or
larger than FD_SETSIZE will result in undefined behavior. Moreover, POSIX requires fd to be a valid file descriptor.

這一點包括之前的我,是很多人沒有注意到的,并且云風大神有篇博文《一起 select 引起的崩潰》也描述了這個問題。

可以看出在Linux系統select也是不安全的,若想使用,得小心翼翼的確認fd是否達到1024,但這很難做到,不然還是老老實實的用poll或epoll吧。

扯得有點遠了,但也引出了本片文章要敘述的主題,就是Linux系統下fd值是怎么分配確定,大家都知道fd是int類型,但其值是怎么增長的,在下面的內容中我對此進行了一點分析,以2.6.30版本的kernel為例,歡迎拍磚。

首先得知道是哪個函數進行fd分配,對此我以pipe為例,它是分配fd的一個典型的syscall,在fs/pipe.c中定義了pipe和pipe2的syscall實現,如下

  1. SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)  
  2. {  
  3.     int fd[2];  
  4.     int error;  
  5.  
  6.     error = do_pipe_flags(fd, flags);  
  7.     if (!error) {  
  8.         if (copy_to_user(fildes, fd, sizeof(fd))) {  
  9.             sys_close(fd[0]);  
  10.             sys_close(fd[1]);  
  11.             error = -EFAULT;  
  12.         }  
  13.     }  
  14.     return error;  
  15. }  
  16.  
  17. SYSCALL_DEFINE1(pipe, int __user *, fildes)  
  18. {  
  19.     return sys_pipe2(fildes, 0);  

進一步分析do_pipe_flags()實現,發現其使用get_unused_fd_flags(flags)來分配fd的,它是一個宏

#define get_unused_fd_flags(flags) alloc_fd(0, (flags)),位于include/linux/fs.h中

好了咱們找到了主角了,就是alloc_fd(),它就是內核章實際執行fd分配的函數。其位于fs/file.c,實現也很簡單,如下

  1. int alloc_fd(unsigned start, unsigned flags)  

  2. {  

  3.     struct files_struct *files = current->files;  

  4.     unsigned int fd;  

  5.     int error;  

  6.     struct fdtable *fdt;  

  7.  

  8.     spin_lock(&files->file_lock);  

  9. repeat:  

  10.     fdt = files_fdtable(files);  

  11.    fd = start;  

  12.     if (fd < files->next_fd)  

  13.         fd = files->next_fd;  

  14.  

  15.     if (fd < fdt->max_fds)  

  16.         fd = find_next_zero_bit(fdt->open_fds->fds_bits,  

  17.                        fdt->max_fds, fd);  

  18.  

  19.     error = expand_files(files, fd);  

  20.     if (error < 0)  

  21.         goto out;  

  22.  

  23.     /*  

  24.      * If we needed to expand the fs array we  

  25.      * might have blocked - try again.  

  26.      */  

  27.     if (error)  

  28.         goto repeat;  

  29.  

  30.     if (start <= files->next_fd)  

  31.         files->next_fd = fd + 1;  

  32.  

  33.     FD_SET(fd, fdt->open_fds);  

  34.     if (flags & O_CLOEXEC)  

  35.         FD_SET(fd, fdt->close_on_exec);  

  36.     else  

  37.         FD_CLR(fd, fdt->close_on_exec);  

  38.     error = fd;  

  39. #if 1  

  40.     /* Sanity check */  

  41.     if (rcu_dereference(fdt->fd[fd]) != NULL) {  

  42.         printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd);  

  43.         rcu_assign_pointer(fdt->fd[fd], NULL);  

  44.     }  

  45. #endif  

  46.  

  47. out:  

  48.     spin_unlock(&files->file_lock);  

  49.     return error;  

在pipe的系統調用中start值始終為0,而中間比較關鍵的expand_files()函數是根據所給的fd值,判斷是否需要對進程的打開文件表進行擴容,其函數頭注釋如下

  1. /*  
  2.  * Expand files.  
  3.  * This function will expand the file structures, if the requested size exceeds  
  4.  * the current capacity and there is room for expansion.  
  5.  * Return <0 error code on error; 0 when nothing done; 1 when files were  
  6.  * expanded and execution may have blocked.  
  7.  * The files->file_lock should be held on entry, and will be held on exit.  
  8.  */ 

此處對其實現就不做深究了,回到alloc_fd(),現在可以看出,其分配fd的原則是

每次優先分配fd值最小的空閑fd,當分配不成功,即返回EMFILE的錯誤碼,這表示當前進程中fd太多。

到此也印證了在公司寫的服務端程序(kernel是2.6.18)中,每次打印client鏈接對應的fd值得變化規律了,假如給一個新連接分配的fd值為8,那么其關閉之后,緊接著的新的鏈接分配到的fd也是8,再新的鏈接的fd值是逐漸加1的。

為此,我繼續找了一下socket對應fd分配方法,發現最終也是 alloc_fd(0, (flags),調用序列如下
socket(sys_call) -> sock_map_fd() -> sock_alloc_fd() -> get_unused_fd_flags()
open系統調用也是用get_unused_fd_flags(),這里就不列舉了。

現在想回頭說說開篇的select的問題。由于Linux系統fd的分配規則,實際上是已經保證每次的fd值盡量的小,一般非IO頻繁的系統,的確一個進程中fd值達到1024的概率比較小。因而對此到底是否該棄用select,還不能完全地做絕對的結論。如果設計的系統的確有其他措施保證fd值小于1024,那么用select無可厚非。

但在網絡通訊程序這種場合是絕不應該作此假設的,所以還是盡量的不用select吧!!

原文鏈接:http://www.cnblogs.com/lanyuliuyun/p/3946564.html

責任編輯:牛小雨 來源: lanyuliuyun的博客
相關推薦

2009-11-11 10:22:15

linux系統時間操作系統

2021-09-14 09:49:12

Linuxsocket fd網絡

2020-11-04 11:25:33

Linux目錄命令

2011-08-22 15:39:38

Linux

2011-04-21 09:54:14

Linuxiptables

2011-08-16 14:18:09

UbuntuLinuxLinuxwindows

2009-09-07 09:56:02

Linux系統LVM擴充Linux

2011-03-09 13:02:15

LinuxLAMP安裝

2009-07-01 09:13:10

Linux

2009-08-06 19:37:17

2009-03-30 14:32:15

LinuxNetware服務器

2009-06-25 08:53:03

Linux操作系統

2011-01-11 16:00:13

Linux軟件安裝

2011-03-21 15:42:14

LinuxNagios

2011-03-03 15:21:11

2012-11-16 13:26:16

2010-05-28 11:05:56

Linux下dhcp測

2009-06-29 09:21:41

Linux

2009-06-30 10:35:36

Linux

2012-02-06 09:40:25

點贊
收藏

51CTO技術棧公眾號

欧美婷婷久久| 九九精品在线观看| 凹凸日日摸日日碰夜夜爽1| 五月激情婷婷综合| 国产黄大片在线观看画质优化| 欧美男男激情freegay| 亚洲一区二区三区四区五区午夜| 亚洲男人天堂久| av免费网站观看| 日本欧美在线视频免费观看| 中文字幕视频精品一区二区三区| 一卡二卡三卡日韩欧美| 精品久久精品久久| 在线播放成人av| 国产精品sm| 亚洲色图综合网| 中文字幕一区二区在线观看视频 | 国产福利视频一区二区三区| 97精品国产91久久久久久| 成人黄色片视频| 国产福利第一页| 国产精品视区| 久久久久999| 久久精品综合视频| 精品视频在线观看网站| 色综合网站在线| av资源站久久亚洲| 激情无码人妻又粗又大| 亚洲va欧美va人人爽成人影院| 精品国产91久久久久久| 亚洲高清乱码| 日本a一级在线免费播放| 精品一区二区三区影院在线午夜 | 国产在线观看不卡| 久久午夜鲁丝片午夜精品| 精品久久久久久久久久久下田| 精品成人在线观看| 成人综合久久网| 成人影院大全| 精品日本美女福利在线观看| 中文字幕中文字幕在线中心一区| 无码人妻精品一区二| 久久成人国产精品入口| 白白色在线观看| 亚洲天天做日日做天天谢日日欢 | 好吊色欧美一区二区三区视频| 中文字幕乱码中文字幕| 亚洲激情视频| 欧美激情精品在线| 不许穿内裤随时挨c调教h苏绵 | 成人国产精品一区| 日韩不卡在线播放| 韩国亚洲精品| 欧美日本亚洲视频| 国产97免费视频| 久久激情电影| 中文字幕在线看视频国产欧美| 性久久久久久久久久| 成人性生交大片免费看中文视频| 欧美一级久久久| 三级黄色片免费看| 国产精品日韩精品在线播放| 亚洲色图在线视频| 天天久久人人| av黄色在线观看| 麻豆精品一二三| 国产精品久久久久久久电影| 国产伦精品一区二区三区视频我| 99综合视频| 欧美性在线视频| 中文字幕黄色片| 国产精品探花在线观看| 亚洲国产精彩中文乱码av在线播放| 无码人妻久久一区二区三区蜜桃| 亚洲电影一区| 亚洲成人a级网| 黄色免费看视频| 亚洲动漫在线观看| 国产一区二区美女视频| 超碰人人人人人人人| 国产精品黑丝在线播放| 久久综合九色九九| yy6080午夜| 日本一级二级视频| 自拍偷自拍亚洲精品被多人伦好爽| 91看片淫黄大片一级| 九色视频成人porny| 青青色在线视频| 欧美国产一区在线| xxxxxx在线观看| 在线观看v片| 色久优优欧美色久优优| 中文字幕国产免费| 99re91这里只有精品| 亚洲久久久久久久久久| 少妇太紧太爽又黄又硬又爽小说| 在线一区电影| 欧洲亚洲免费视频| 国产伦一区二区三区色一情| www.欧美色| 狠狠色丁香婷婷综合| 成人午夜影院在线观看| 青青操在线视频| 亚洲欧美日韩精品久久久久| 欧美不卡在线播放| 日韩精品一页| 日韩电影在线观看中文字幕| 中文字幕乱码av| 亚洲国产日本| 91精品在线一区| 日本福利片高清在线观看| 最新日韩在线视频| 男人天堂网视频| 欧美日韩中出| 中国日韩欧美久久久久久久久| a级黄色片免费看| 日日摸夜夜添夜夜添亚洲女人| 亚洲一区免费网站| 国产高清自拍视频在线观看| 亚洲综合清纯丝袜自拍| 91蝌蚪视频在线观看| 日韩欧美久久| 色阁综合伊人av| av大片在线免费观看| 国产一区二区三区日韩| 日韩视频专区| 美女露胸视频在线观看| 在线播放欧美女士性生活| 丰满少妇一区二区三区| 欧美视频四区| 91免费精品国偷自产在线| 国产一级在线| 精品久久久视频| 苍井空张开腿实干12次| 日本道不卡免费一区| 欧美在线视频一区| 日韩一级免费毛片| 一区二区三区在线视频观看 | 日韩视频在线永久播放| 久久久久99精品成人| 国产精品社区| 国产在线精品一区二区三区》| 菠萝蜜视频国产在线播放| 欧美日韩一区二区在线观看视频 | 永久免费成人代码| 精品二区久久| 999热视频在线观看| 激情成人四房播| 一区二区三区精品在线| 在线观看国产一级片| 国产日韩视频在线| 欧美亚洲国产精品| 头脑特工队2免费完整版在线观看| 99re视频这里只有精品| 国产 国语对白 露脸| 国产成年精品| 大胆欧美人体视频| 国产女同91疯狂高潮互磨| 中文字幕一区二区三区在线观看 | 亚洲日本无吗高清不卡| 国模一区二区| 日韩在线精品视频| 国产又黄又大又粗的视频| 成人免费一区二区三区视频| 亚洲小视频网站| 综合久久亚洲| 国产精品有限公司| 小早川怜子影音先锋在线观看| 日韩精品极品视频免费观看| 天天操夜夜操视频| 国产午夜精品久久| 一级片视频免费观看| 999国产精品视频| 91中文在线视频| 欧美精品色婷婷五月综合| 少女频道在线观看高清 | 久久久久成人精品| 污视频在线免费观看| 欧美日韩国产专区| av网在线播放| 激情文学综合丁香| 日本黄色片一级片| 伊人久久大香线蕉| 国产在线观看一区二区三区| 成人性生交大片免费看在线播放| 日韩国产中文字幕| 一级黄色片网站| 亚洲综合色成人| 精品无码国产污污污免费网站| 久久99精品久久久久久久久久久久 | 国产午夜亚洲精品羞羞网站| 国产原创精品在线| 欧美私人啪啪vps| 日本欧美色综合网站免费| 黄色成人在线观看网站| 久久69精品久久久久久久电影好| 无码精品人妻一区二区| 欧美系列一区二区| 国产乱国产乱老熟300部视频| 在线观看视频日韩| 四虎永久国产精品| 亚洲高清999| 国产精品久久久久久久久男| 天堂成人av| 亚洲色图狂野欧美| 黑人精品一区二区| 一区二区三区四区国产精品| 精品无码在线视频| 黑人精品欧美一区二区蜜桃| 免费无遮挡无码永久视频| 国产精品久久久久久麻豆一区软件| 国精产品一区二区| 91精品麻豆| 国产成+人+综合+亚洲欧洲| 免费国产羞羞网站视频| 欧美色涩在线第一页| 国产亚洲精品码| 国产精品人妖ts系列视频| 色一情一乱一伦一区二区三区日本| 中文字幕午夜精品一区二区三区| 欧美在线激情| 玖玖玖免费嫩草在线影院一区| 成人免费观看a| 9191在线视频| 国产成人一区二区三区影院| 91免费版黄色| av日韩在线免费观看| 国产成人精品一区| 美女av在线免费看| 欧美黄网免费在线观看| 久cao在线| 中文字幕一区二区三区电影| 欧美一区二区视频| 亚洲国产欧美一区二区三区久久| 99在线精品视频免费观看软件 | www.色综合.com| 久久久久久久久久久影视| 麻豆成人久久精品二区三区红| 777米奇影视第四色| 亚洲精品乱码| 免费的av在线| 综合国产精品| 日本一道在线观看| 欧美a级片一区| 五月天激情图片| 欧美在线三区| 免费cad大片在线观看| 天天做综合网| 国产福利片一区二区| 中文幕av一区二区三区佐山爱| 2019中文字幕在线观看| 99久久精品免费看国产小宝寻花| 欧美大尺度在线观看| 精品国产99久久久久久| 色婷婷综合久久久久| 91社区在线观看| 中文字幕日韩有码| 日本在线观看www| 精品国产欧美成人夜夜嗨| 999国产在线视频| 这里只有精品在线观看| 在线免费看黄| 久久精品国产精品| 怡红院在线观看| 久久免费精品日本久久中文字幕| 1024在线看片你懂得| 性视频1819p久久| 性感女国产在线| 国产97色在线|日韩| jizz亚洲女人高潮大叫| 国产精品日本精品| 国产亚洲精aa在线看| av激情久久| 欧美自拍一区| 日韩欧美精品一区二区| 91麻豆国产自产在线观看亚洲| 国产又粗又硬又长| 激情欧美亚洲| 日本熟妇人妻xxxxx| 日本va欧美va精品| 在线免费观看日韩欧美| 影音先锋亚洲天堂| 91福利在线看| 国产高中女学生第一次| 亚洲国产天堂久久国产91| 久草福利在线视频| 久久综合伊人77777| 2020av在线| 国产精品精品一区二区三区午夜版| 日本久久二区| 狠狠干一区二区| gogogo高清在线观看一区二区| 一区二区国产日产| 亚洲福利久久| 天天干天天干天天干天天干天天干| 狠狠色2019综合网| 五月天丁香社区| 国产日韩精品视频一区| 亚洲伦理一区二区三区| 香蕉加勒比综合久久| 国产成人a v| 日韩欧美你懂的| 国产日本在线| 久久久久久久久久婷婷| xxxxx.日韩| 黄色91av| 欧美日韩1区2区3区| 亚洲综合在线网站| 国产69精品一区二区亚洲孕妇| 变态另类ts人妖一区二区| 亚洲一区二区三区四区在线观看 | 日本电影亚洲天堂一区| 国产精品毛片一区视频播| 亚洲国产精品va在线观看黑人| 久热国产在线| 欧美最顶级的aⅴ艳星| av动漫精品一区二区| 亚洲国产欧美一区二区三区不卡| 日韩视频一区| 欧美专区第二页| 欧美激情在线免费观看| 18精品爽视频在线观看| 欧美伊人久久久久久午夜久久久久| 亚洲精品97久久中文字幕无码| www日韩欧美| a成人v在线| 日韩wuma| 久久裸体视频| 日韩网站在线免费观看| 久久精品999| 精品国产av无码| 久久九九久精品国产免费直播| 黄色一级视频在线观看| 欧美日韩不卡在线| 福利成人在线观看| 奇米四色中文综合久久| 成人爽a毛片| 精品国产av无码一区二区三区| 亚洲麻豆一区| 国产精品嫩草69影院| 亚洲男人天堂一区| 国产免费黄色片| zzijzzij亚洲日本成熟少妇| 少妇一级淫片免费看| 国产69精品久久777的优势| 青青草视频成人| 精品福利一区二区| 天天干免费视频| 国模gogo一区二区大胆私拍| youjizz欧美| 日韩精品一区在线视频| 成人黄色综合网站| 日韩欧美大片在线观看| 91福利社在线观看| 男女污视频在线观看| 欧美一级成年大片在线观看| 欧美黑人做爰爽爽爽| 黄色免费福利视频| 2021国产精品久久精品| 天堂中文在线网| 亚洲欧美一区二区精品久久久| 亚洲1234区| 亚洲国产欧美日韩| 国产一区亚洲一区| 欧美黄色免费观看| 亚洲成人黄色在线观看| caoporn视频在线| 久久国产精品久久精品国产| 先锋影音国产一区| 国产亚洲精品精品精品| 欧美日韩精品欧美日韩精品一| 日本韩国在线视频爽| 成人网址在线观看| 欧美激情自拍| 秘密基地免费观看完整版中文| 亚洲午夜精品在线| 深夜福利免费在线观看| 国产成人精品日本亚洲| 91综合久久一区二区| 国产成人精品综合久久久久99| 午夜欧美在线一二页| 国产尤物视频在线| 91传媒视频在线观看| 伊人成年综合电影网| 少妇精品一区二区三区| 欧美日韩另类一区| 搞黄网站在线看| 视频一区不卡| 国产精品77777| 中国一级免费毛片| 日韩视频免费看| 成人爽a毛片| 亚洲福利精品视频| 亚洲一区二区影院| www.久久热.com| 国产福利久久精品| 日韩精品电影一区亚洲| 18岁成人毛片| 亚洲欧美日韩精品| 色妞ww精品视频7777|