亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

關于getpw系列函數返回的靜態區域

2024-06-28 13:21:09
字體:
來源:轉載
供稿:網友
關于getpw系列函數返回的靜態區域

  首先說一下什么是getpw系列函數,它主要是指這些函數:

  

  這些函數根據一個用戶名(getpwnam和getpwnam_r兩個函數)或者一個用戶ID(getpwuid和getpwuid_r)來獲取這個用戶在/etc/passwd中相應的條目信息,并把這些信息存放在一個struct passwd的結構體里面,然后再把這個結構體的指針返回。問題就出在這個存儲用戶信息的結構體上面,它是由getpw函數在程序中自定義的一塊靜態存儲區,而且每調用一次getpw函數,這個靜態存儲區就會被重寫一次。比如下面這段代碼:

 1 #include<errno.h> 2 #include<pwd.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include<stdarg.h> 6 #include<stdio.h> 7 #include<sys/types.h> 8  9 #define BUFSIZE 51210 11 void err_exit(char *fmt,...);12 13 int main(int argc,char *argv[])14 {15     16     struct passwd *mistr;17     struct passwd *rootstr;18 19     if(NULL == (mistr=getpwnam("michael")))20     err_exit("[getpwnam]<mi>:");21     if(NULL == (rootstr=getpwnam("root")))22     err_exit("[getpwnam]<root>:");23 24     PRintf("name = %s/n",mistr->pw_name);25     printf("name = %s/n",rootstr->pw_name);26 27     return 0;28 }

  我想要獲取michael用戶和root用戶的信息,然后我很異想天開得創建了兩個指針,一個指向michael用戶的信息,一個指向root用戶的信息,以為這樣就能分別保存兩個用戶的信息了,然后發現程序的運行結果如下圖:

  

  發現兩次打印的信息,都是root,說明后面調用的getpwnam函數重寫了struct passwd這個結構體,把前面調用getpwnam函數時寫入的michael用戶的信息給覆蓋了。

  這個就是getpwnam_r和getpwuid_r函數出現的原因,為了防止多線程程序因為競爭而產生錯誤。關于這兩個函數getpwnam的文檔中是這樣描述的:

  

  這兩個函數可以將用戶信息存放在用戶定義的struct passwd結構體中,而不一定非得要放在函數定義的,可能被重寫的靜態區域中,這樣多線程程序運行的時候就可以避免競爭了。

  接下來再來說我的一個新的發現,就是getpw函數調用的時候是有鎖的,也就是說同一個進程中,如果一個getpw函數正在運行,另一個getpw函數是無法運行的。

  這個發現是我在運行《APUE》的程序清單10-2的時候發現的,《APUE》上面的代碼如下(不是完全相同,自己重寫了一下^_^):

 1 /** 2  *  可重入函數的概念就是可以在被調用了一半的時候被打斷,然后再來從新調用,這里的getpwnam就是一個不可重入函數 3  * ,因為getpwnam函數會修改一個靜態變量來保存讀出的用戶信息,如果調用了一半再被重新調用,則有可能會讓原來的 4  * 信息被覆蓋掉 5  * 6  * 現在getpwname函數可能有鎖,信號處理函數再來調用這個函數會卡死 7  */ 8  9 #include<errno.h>10 #include<pwd.h>11 #include<signal.h>12 #include<string.h>13 #include<stdlib.h>14 #include<stdarg.h>15 #include<stdio.h>16 #include<sys/types.h>17 #include<unistd.h>18 19 #define BUFSIZE 51220 21 void err_exit(char *fmt,...);22 int err_dump(char *fmt,...);23 int err_ret(char *fmt,...);24 25 /**26  *  本函數用來處理SIGALRM信號27  */28 void sig_alrm(int signo)29 {30     struct passwd *rootstr;31 32     printf("In signal SIGALRM handler/n");33 34     if(NULL == (rootstr=getpwnam("root")))35     err_exit("[getpwnam]<root>:");36     else37     printf("pw_name = %s/n",rootstr->pw_name);38 39     alarm(1);40 }41 42 int main(int argc,char *argv[])43 {44     45     struct passwd *mistr;46     signal(SIGALRM,sig_alrm);47 48     /**49      *    alarm函數用來在1秒鐘之后發送一個SIGALRM信號給本程序50      */51     alarm(1);52 53     for(;;)54     {55     if(NULL == (mistr=getpwnam("michael")))56         err_exit("[getpwnam]<mi>:");57     if(strcmp(mistr->pw_name,"michael"))58         printf("結果錯誤,讀出的用戶名是:%s/n",mistr->pw_name);59     }60 61     return 0;62 }

  這個程序的流程是主函數調用getpwname獲取michael用戶的信息,同時通過alarm函數給自己發送SIGALRM信號,在SIGALRM的信號處理函數中,我們再來調用getpwnam函數獲取root用戶的信息,作者想要的結果是主函數不斷讀取michael用戶的信息,但是SIGALRM信號處理函數獲取了root用戶的信息,所以最后主函數最后打印就有可能是root用戶的信息,此時主函數就打印讀取出錯。

  但是在程序運行的過程中我的電腦上卻會發生死鎖的情況,運行結果如下圖所示:

  

  到此時程序就卡死了,不會再繼續下去了。

  后來我又用gdb把這個程序調試了一下,首先在32行那里增加一個斷點,然后再用si命令一步一步地執行匯編指令,執行的過程如下:

  

  si命令在調試時是會進入函數內部的,所以我在進入getpwnam函數之后又一步一步地深入,最后我發現我的函數卡在了__lll_lock_wait_private()這個地方,函數的調用棧如下:

  

  前4行表示接受到了信號之后的處理過程,最后函數卡在了__lll_lock_wait_private()這個函數這里。我google了一下這個函數,在這里找到了它的實現。這個有點慚愧,看了半天愣是沒看懂那個實現代碼是是什么意思,不過我在那里看到了那個文件是一個線程庫,所以我猜getpwnam函數的執行過程應該是這樣的:

  在getpwnam函數內部,具體還是要調用getpwnam_r函數來實現的(從上面函數棧截圖的5~8行可以看出來),在getpwnam函數內部調用getpwnam_r函數的時候,先要上一個線程鎖,調用完成之后,再來解鎖這個線程鎖,這樣來確保getpwnam函數每次只會被一個線程調用。

  而在上面的代碼中,主函數中的getpwnam函數沒有解鎖,就被暫停運行了,而信號處理函數(sig_alrm)函數中的getpwnam再來調用的時候,就會等待主函數中的getpwnam解鎖,而主函數又是暫停的,這樣就會產生死鎖了!

  OK,這就是我的分析了, 后面那個線程鎖那里我感覺還不是太了解,講的不是太好,還望見諒,如果哪位關于這部分有更深的了解,還望不吝賜教!


上一篇:curl命令詳解

下一篇:光標操作快捷鍵

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品手机播放| 91国内产香蕉| 日韩一区二区久久久| 中日韩午夜理伦电影免费| 亚洲视频在线看| 美乳少妇欧美精品| 欧美激情奇米色| 日韩av在线网址| 另类少妇人与禽zozz0性伦| 精品国内产的精品视频在线观看| 亚洲免费电影在线观看| 国产精品视频免费观看www| 一区二区三区视频免费在线观看| 欧美多人乱p欧美4p久久| 亚洲国产精品专区久久| 亚洲女人被黑人巨大进入| 精品福利樱桃av导航| 57pao精品| 日本成人激情视频| 国内精品久久久久久影视8| 国产欧美在线播放| 欧美日韩电影在线观看| 米奇精品一区二区三区在线观看| 北条麻妃一区二区三区中文字幕| 亚洲精品中文字幕女同| 国产热re99久久6国产精品| 欧美日韩免费区域视频在线观看| 日韩精品在线视频美女| 国产精品电影在线观看| 久久精品国产96久久久香蕉| 一区二区三区四区精品| 日韩在线免费视频| 午夜剧场成人观在线视频免费观看| 亚洲大尺度美女在线| 精品国产一区久久久| 91免费福利视频| 国产视频久久久久| 热门国产精品亚洲第一区在线| 欧美日韩另类在线| 亚洲国产成人在线播放| 少妇精69xxtheporn| 91国语精品自产拍在线观看性色| 久久精品国产亚洲精品2020| 久久免费国产精品1| 久久视频在线免费观看| 韩曰欧美视频免费观看| 久久精品成人欧美大片古装| 中文字幕亚洲天堂| 欧美亚洲成人网| 国内自拍欧美激情| 亚洲视频一区二区| 国产欧美一区二区三区久久人妖| 欧美俄罗斯性视频| 成人国产在线激情| 亚洲第一级黄色片| 国产欧美一区二区三区四区| 95av在线视频| 亚洲精品网站在线播放gif| 成人精品久久一区二区三区| 日韩在线中文字幕| 欧美激情aaaa| 国色天香2019中文字幕在线观看| 成人国产精品免费视频| 亚洲jizzjizz日本少妇| 日韩精品一区二区三区第95| 欧美性生活大片免费观看网址| 亚洲视频第一页| 久久人人看视频| 久久久久久久久久久免费| 91亚洲国产成人精品性色| 日韩美女在线播放| 中文字幕亚洲欧美日韩2019| 中文国产成人精品久久一| 日韩av电影在线播放| 欧美日韩一区二区在线播放| 国产视频在线一区二区| 欧美精品videofree1080p| 亚洲无线码在线一区观看| 欧美猛交ⅹxxx乱大交视频| 97视频在线免费观看| 国产suv精品一区二区| 欧美成人免费在线观看| 日韩精品在线免费观看视频| 国产精品网红福利| 亚洲精品suv精品一区二区| 中文字幕欧美日韩va免费视频| 日韩av中文在线| 一本久久综合亚洲鲁鲁| 国内外成人免费激情在线视频网站| 国产精品av在线播放| 欧美极品少妇xxxxⅹ免费视频| 久久久精品国产网站| 亚洲精品美女久久久久| 4444欧美成人kkkk| 久久久影视精品| 欧洲成人免费视频| 日韩精品有码在线观看| 97超级碰在线看视频免费在线看| 97免费中文视频在线观看| 国产精品视频免费在线| 亚洲国产精品久久| 色妞欧美日韩在线| 国产精品久久久久99| 国产丝袜精品第一页| 日韩电影在线观看免费| 丝袜情趣国产精品| 亚洲美女精品成人在线视频| 久久国产精品偷| 国产在线视频欧美| 久久久久在线观看| 日韩麻豆第一页| 欧美激情欧美激情在线五月| 538国产精品一区二区免费视频| 精品伊人久久97| 国产精品女主播| 久久久人成影片一区二区三区观看| 欧美亚洲视频在线观看| 欧美性xxxx极品hd满灌| 国产精品18久久久久久首页狼| 日韩在线观看免费全集电视剧网站| 日产精品久久久一区二区福利| 国产精品人人做人人爽| 欧美午夜电影在线| 日韩av片免费在线观看| 日韩精品免费在线播放| 国产精品第3页| 日韩毛片在线看| 成人免费视频xnxx.com| 国产成人激情视频| 久久的精品视频| 亚洲成人免费在线视频| 久久亚洲精品小早川怜子66| 久久这里只有精品视频首页| 伊人伊人伊人久久| 成人有码视频在线播放| 国产视频精品免费播放| 欧美日韩国产在线播放| 91精品久久久久久久久久久久久久| 久久亚洲一区二区三区四区五区高| 最近2019年日本中文免费字幕| 国产噜噜噜噜噜久久久久久久久| 日韩av网站导航| 日韩免费观看网站| 日韩欧美在线一区| 亚洲欧洲一区二区三区在线观看| 国产成人aa精品一区在线播放| 国产精品永久免费| 久久久国产精品一区| 中文字幕亚洲无线码a| 成人黄色网免费| 日韩在线视频免费观看| 欧美另类在线播放| 久久久国产一区二区| 久久久久久久久久久av| 欧美日韩ab片| 色婷婷亚洲mv天堂mv在影片| 日韩中文字幕视频在线观看| 国产精品久久久久久婷婷天堂| 日本国产欧美一区二区三区| 中文字幕久久精品| 久久影院免费观看| 久久久国产视频| 国产91ⅴ在线精品免费观看| 欧美日韩国产一区二区三区|