天天看點

家庭作業第十章,第九章,第十一章

10.8

由于stat函數和fstat函數在功能上很相似,都是檢索檔案的資訊,隻是stat函數以檔案名作為輸入,而fstat函數是以檔案描述符作為輸入,是以隻需把Stat(argv[1],&stat)改為fstat(atoi(argv[1]),&stat)即可實作功能

include “csapp.h”

Int main(int argc,char **argv)

{

struct stat stat;

char type,readok;

fstat(atoi(argv[1]),&stat);

if(S_ISREG(stat.st_mode))

type=”regular”;

else if(S_ISDIR(stat.st_mode))

type=”directory”;

else

type=”other”;

if((stat.st_mode & S_IRUSR))

readok=”yes”;

readok=”no”;

printf(“type: %s,read:%s\n”,type,readok);

exit(0);

}

10.9

輸入重定向到了foo.txt,然而3這個描述符是不存在的。

說明foo.txt并沒有單獨的描述符3。

是以Shell執行的代碼應該是這樣的:

if (Fork() == 0) {/* Child */

int fd = open("foo.txt", O_RDONLY, 0);

dup2(fd, 1);

close(fd);

Execve("fstatcheck", argv, envp);

9.11

A.虛拟位址:0x027c

13	12	11	10	9	8	7	6	5	4	3	2	1	0

0	0	0	0	1	0	0	1	1	1	1	1	0	0
           

B.位址翻譯

參數				值

VPN				 0x09

TLB索引		   	0x01

TLB标記			0x02

TLB命中			No

缺頁				No

PPN				0x17
           

C.實體位址格式

11	10	9	8	7	6	5	4	3	2	1	0

0	1	0	1	1	1	1	1	1	1	0	0
           

D.實體位址引用

參數				值

位元組偏移			0x0

緩存索引			0xF

緩存标記			0x17

緩存命中			No

傳回緩存位元組	  		-
           

9.12

A.虛拟位址:0x03a9

13	12	11	10	9	8	7	6	5	4	3	2	1	0

0	0	0	0	1	1	1	0	1	0	1	0	0	1
           
參數				值

VPN				0x0E

TLB索引		   0x02

TLB标記		   0x03

TLB命中			No

缺頁				No

PPN				0x11
           
11	10	9	8	7	6	5	4	3	2	1	0

0	1	0	0	0	1	1	0	1	0	0	1
           
參數				值

位元組偏移		  0x1

緩存索引		  0xA

緩存标記		  0x11

緩存命中		   No

傳回緩存位元組		  -
           

9.13

A.虛拟位址:0x0040

13	12	11	10	9	8	7	6	5	4	3	2	1	0

0	0	0	0	0	0	0	1	0	0	0	0	0	0

B.位址翻譯

參數				值

VPN				0x01

TLB索引		   0x01

TLB标記		   0x00

TLB命中			No

缺頁				Yes

PPN				   -
           

9.15

請求			塊大小			塊頭部

malloc(3)		8			0x9

malloc(11)		16			0x11

malloc(20)		24			0x19

malloc(21)		32			0x21
           

9.19

1) a; 對于夥伴系統,如果要申請大小為33的空間,那麼需要配置設定64個空間。如果申請大小為65的空間,那麼塊大小就需要128,是以最多可能有約50%的空間被浪費。b中,最佳适配要搜尋所有空間,是以肯定比首次适配要慢一些。c,邊界标記主要功能是釋放一個塊時,能立即和前後空閑塊合并。如果空閑塊不按順序排列的話,其實也能夠和前一個或者後一個空閑塊進行合并,但如果要和前後一起合并,可能會有些困難,那需要搜尋前後塊在空閑連結清單中的位置,并且删除一個再進行合并。可以參考P576,LIFO方法。d,其實任何配置設定器都可能有外部碎片,隻要剩餘的空閑塊大小和足夠但是單個都不夠,就會産生外部碎片。


2) d; 塊大小遞增,那麼最佳适配法找到的塊和首次适配找到的塊是同一個,因為最佳适配總是想找一個剛好大于請求塊大小的空閑塊。a,塊大小遞減,首次适配很容易找到,是以配置設定性能會很高。b,最佳适配方法無論怎樣,都要搜尋所有的連結清單(除非維護成塊大小遞增的連結清單)。c,是比對的最小的。


3) c; 保守的意思就是所有可能被引用的堆都會被标記,int像指針,是以可能認為它表示的位址是正在被引用的(實際上它隻是個int)。
           

11.9

serve_static中的存儲器映射語句改為:

srcfd = open(filename, O_RDONLY, 0);

srcp = (char*)malloc(sizeof(char)*filesize);

rio_readn(srcfd, srcp, filesize);

close(srcfd);

rio_writen(fd, srcp, filesize);

free(srcp);
           

12.24

可重入函數:當它們被多個線程調用時,不會引用任何共享資料。

滿足下面條件之一的多數是不可重入函數:

1.使用了靜态資料結構

2.調用了malloc或free

3.調用了标準I/O函數;标準I/O庫很多實作都一不可重入的方式使用全局資料結構

4.進行了浮點運算。許多的處理器/編譯器中,浮點一般都是不可重入的(浮點運算大多使用協處理器或者軟體模拟來實作)

rio_readn(int fd,void *usrbuf,size_t n)是不可重入函數,因為每次調用都共享read(fd,bufp,nleft),使用全局資料結構

rio_writen(int fd,void *usrbuf,size_t n)是不可重入函數, 使用全局資料結構

rio_read(int fd,void *usrbuf,size_t n)是不可重入函數,使用全局資料結構

rio_readlineb(int fd,void *usrbuf,size_t maxlen)是不可重入函數,使用全局資料結構

rio_readnb(int ,void *usrbuf,size_t n)是不可重入函數,使用全局資料結構