博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《CSAPP》(第3版)答案(第十二章)(一)
阅读量:4169 次
发布时间:2019-05-26

本文共 9273 字,大约阅读时间需要 30 分钟。

《CSAPP》(第3版)答案(第十二章)(一)

P16

#include 
#include "csapp.h"void *thread(void *vargp);#define DEFAULT 4int main(int argc, char* argv[]) {
int N; if (argc > 2) unix_error("too many param"); else if (argc == 2) N = atoi(argv[1]); else N = DEFAULT; int i; pthread_t tid; for (i = 0; i < N; i++) {
Pthread_create(&tid, NULL, thread, NULL); } Pthread_exit(NULL);}void *thread(void *vargp) {
printf("Hello, world\n"); return NULL;}

P17

  • A
    主线程没有等待另一个线程。
  • B
#include "csapp.h"void *thread(void *vargp);int main(){
pthread_t tid; Pthread_create(&tid, NULL, thread, NULL); // exit(0); Pthread_exit(NULL);}/* Thread routine */void *thread(void *vargp){
Sleep(1); printf("Hello, world!\n"); return NULL;}

P18

  • A
    不安全
  • B
    安全
  • C
    不安全

P19

#include 
#include "csapp.h"#define WRITE_LIMIT 100000#define PEOPLE 4static int readtimes;static int writetimes;static int readcnt;// if a reader is waiting when writing, reader first next roundstatic int reader_first;sem_t mutex, w;void *reader(void *vargp) {
while (1) {
P(&mutex); readcnt++; if (readcnt == 1) P(&w); V(&mutex); /* Critical section */ readtimes++; reader_first = 0; /* Critical section */ P(&mutex); readcnt--; if (readcnt == 0) V(&w); V(&mutex); }}void *writer(void *vargp) {
while (1) {
if (reader_first == 1) continue; P(&w); /* Critical section */ writetimes++; if (writetimes == WRITE_LIMIT) {
printf("read/write: %d/%d\n", readtimes, writetimes); exit(0); } /* Critical section */ // if a reader is waiting, reader first next round if (readcnt == 1) reader_first = 1; V(&w); }}void init(void) {
readcnt = 0; readtimes = 0; writetimes = 0; reader_first = 0; Sem_init(&w, 0, 1); Sem_init(&mutex, 0, 1);}int main(int argc, char* argv[]) {
int i; pthread_t tid; init(); for (i = 0; i < PEOPLE; i++) if (i%2 == 0) Pthread_create(&tid, NULL, reader, NULL); else Pthread_create(&tid, NULL, writer, NULL); Pthread_exit(NULL); exit(0);}

P20

#include 
#include "csapp.h"#define WRITE_LIMIT 100000#define PEOPLE 20 // 10 reader and 10 writer#define N 5static int readtimes;static int writetimes;sem_t mutex;sem_t readercnt;void *reader(void *vargp) {
while (1) {
P(&readercnt); P(&mutex); readtimes++; V(&mutex); V(&readercnt); }}void *writer(void *vargp) {
while (1) {
P(&mutex); writetimes++; if (writetimes == WRITE_LIMIT) {
printf("read/write: %d/%d\n", readtimes, writetimes); exit(0); } V(&mutex); }}void init(void) {
readtimes = 0; writetimes = 0; Sem_init(&mutex, 0, 1); Sem_init(&readercnt, 0, N);}int main(int argc, char* argv[]) {
int i; pthread_t tid; init(); for (i = 0; i < PEOPLE; i++) {
if (i%2 == 0) Pthread_create(&tid, NULL, reader, NULL); else Pthread_create(&tid, NULL, writer, NULL); } Pthread_exit(NULL); exit(0);}

P21

#include 
#include "csapp.h"#define WRITE_LIMIT 100000#define PEOPLE 4static int readtimes;static int writetimes;static int writecnt;sem_t mutex, w;static int number;void *reader(void *vargp) {
while (1) {
// writer first if (writecnt > 0) continue; P(&w); /* Critical section */ readtimes++; /* Critical section */ V(&w); }}void *writer(void *vargp) {
while (1) {
P(&mutex); // one more writer wait to write writecnt++; V(&mutex); P(&w); /* Critical section */ writetimes++; if (writetimes == WRITE_LIMIT) {
printf("read/write: %d/%d\n", readtimes, writetimes); exit(0); } /* Critical section */ V(&w); P(&mutex); // writer has written writecnt--; V(&mutex); }}void init(void) {
writecnt = 0; readtimes = 0; writetimes = 0; Sem_init(&w, 0, 1); Sem_init(&mutex, 0, 1);}int main(int argc, char* argv[]) {
int i; pthread_t tid; init(); for (i = 0; i < PEOPLE; i++) {
if (i%2 == 0) Pthread_create(&tid, NULL, reader, NULL); else Pthread_create(&tid, NULL, writer, NULL); } Pthread_exit(NULL); exit(0);}

P22

#include "csapp.h"/* read line from connfd and echo line to connfd */int echo_line(int connfd);void command(void);int main(int argc, char **argv){
int listenfd, connfd; socklen_t clientlen; struct sockaddr_storage clientaddr; fd_set read_set, ready_set; if (argc != 2) {
fprintf(stderr, "usage: %s
\nuse port 5000 here\n", argv[0]); // default port 5000 listenfd = Open_listenfd("5000"); } else {
listenfd = Open_listenfd(argv[1]); //line:conc:select:openlistenfd } FD_ZERO(&read_set); /* Clear read set */ //line:conc:select:clearreadset FD_SET(STDIN_FILENO, &read_set); /* Add stdin to read set */ //line:conc:select:addstdin FD_SET(listenfd, &read_set); /* Add listenfd to read set */ //line:conc:select:addlistenfd // max n for select int n = listenfd+1; while (1) {
ready_set = read_set; Select(n, &ready_set, NULL, NULL, NULL); //line:conc:select:select if (FD_ISSET(STDIN_FILENO, &ready_set)) //line:conc:select:stdinready command(); /* Read command line from stdin */ if (FD_ISSET(listenfd, &ready_set)) {
//line:conc:select:listenfdready clientlen = sizeof(struct sockaddr_storage); connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // listen to accepted io ports if (connfd+1 > FD_SETSIZE) {
fprintf(stderr, "too many clients\n"); Close(connfd); } n = n > connfd+1 ? n : connfd+1; FD_SET(connfd, &read_set); } // echo one line every time int fd; for (fd = listenfd+1; fd < n; fd++) if (FD_ISSET(fd, &ready_set)) if (echo_line(fd) == -1) {
Close(fd); FD_CLR(fd, &read_set); } }}void command(void) {
char buf[MAXLINE]; if (!Fgets(buf, MAXLINE, stdin)) exit(0); /* EOF */ printf("%s", buf); /* Process the input command */}int echo_line(int connfd) {
ssize_t n; char buf[1]; while ((n = Rio_readn(connfd, buf, 1)) > 0) {
Rio_writen(connfd, buf, n); if (buf[0] = '\n') return 0; } return -1;}

P23

@@ -1,7 +1,5 @@ /*- * 12.23.bug.c - A concurrent echo server based on select- *- * bug in this file+ * 12.23.c - A concurrent echo server based on select  */ #include "csapp.h" @@ -105,15 +103,21 @@     /* If the descriptor is ready, echo a text line from it */     if ((connfd > 0) && (FD_ISSET(connfd, &p->ready_set))) {
p->nready--;- if ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
+ if ((n = rio_readlineb(&rio, buf, MAXLINE)) > 0) {
byte_cnt += n; //line:conc:echoservers:beginecho printf("Server received %d (%d total) bytes on fd %d\n", n, byte_cnt, connfd); Rio_writen(connfd, buf, n); //line:conc:echoservers:endecho }- /* EOF detected, remove descriptor from pool */+ else if (n == 0) {
+ Close(connfd); //line:conc:echoservers:closeconnfd+ FD_CLR(connfd, &p->read_set); //line:conc:echoservers:beginremove+ p->clientfd[i] = -1; //line:conc:echoservers:endremove+ }+ /* n == -1, it's an error */ else {
+ fprintf(stderr, "error in fd %d, close fd %d connection\n", connfd, connfd); Close(connfd); //line:conc:echoservers:closeconnfd FD_CLR(connfd, &p->read_set); //line:conc:echoservers:beginremove p->clientfd[i] = -1; //line:conc:echoservers:endremove

P24

P25

thread safe?

Yes, mutex make it safe
reentrant? (我也不知道reentrant咋翻译)
No, share the same mutex

P26

#include 
#include "csapp.h"/* * struct hostent *gethostbyname(const char *name) * * struct hostent { * char *h_name; * char **h_aliases; * int h_addrtype; * int h_length; * char **h_addr_list; * } */static sem_t mutex;static void init_mutex(void) {
Sem_init(&mutex, 0, 1);}struct hostent *gethostbyname_ts(const char *name, struct hostent *host) {
struct hostent *sharehost; P(&mutex); sharehost = gethostbyname(name); // copy int host->h_addrtype = sharehost->h_addrtype; host->h_length = sharehost->h_length; // copy char * host->h_name = (char*)Malloc(strlen(sharehost->h_name)); strcpy(host->h_name, sharehost->h_name); // copy char ** int i; for (i = 0; sharehost->h_aliases[i] != NULL; i++) {
} host->h_aliases = (char**)Malloc(sizeof(char*) * (i+1)); for (i = 0; sharehost->h_aliases[i] != NULL; i++) {
// copy every char * host->h_aliases[i] = (char*)Malloc(strlen(sharehost->h_aliases[i])); strcpy(host->h_aliases[i], sharehost->h_aliases[i]); } host->h_aliases[i] = NULL; for (i = 0; sharehost->h_addr_list[i] != NULL; i++) {
} host->h_addr_list = (char**)Malloc(sizeof(char*) * (i+1)); for (i = 0; sharehost->h_addr_list[i] != NULL; i++) {
// copy every char * host->h_addr_list[i] = (char*)Malloc(strlen(sharehost->h_addr_list[i])); strcpy(host->h_addr_list[i], sharehost->h_addr_list[i]); } host->h_addr_list[i] = NULL; V(&mutex); return host;}int main(int argc, char* argv[]) {
init_mutex(); struct hostent host; gethostbyname_ts("127.0.0.1", &host); // result in &host return 0;}

P27

I cannot explain.

转载地址:http://kfwai.baihongyu.com/

你可能感兴趣的文章
leetcode 89 Gray Code
查看>>
leetcode 88 Merge Sorted Array
查看>>
leetcode 87 Scramble String(递归+剪枝)
查看>>
win10系统下“python不是内部或外部命令”的解决方法
查看>>
Python的优缺点
查看>>
python中如何区分常量和变量
查看>>
python导入模块的4种方法
查看>>
linux more命令简单使用
查看>>
vi 编辑器超级简单且实用的命令
查看>>
python多行注释和跨行字符串
查看>>
linux终端输出彩色字体
查看>>
一个程序学会python的流程控制
查看>>
python中sys.exit() os._exit() exit() quit()的简单使用
查看>>
linux rm -f rm -rf 命令:删除文件和文件夹
查看>>
ubuntu-14.04.3下安装VMware Tools(虚拟机与主机之间直接复制粘贴)
查看>>
python编写登录接口
查看>>
python字符串处理常用方法
查看>>
linux echo 向文件中追加信息
查看>>
python列表常见方法
查看>>
python打印列表中指定元素的所有下标(5种方法)
查看>>