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

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

P28

没有影响

  • 1
thread 1 thread 2
P(s) P(s)
P(t) P(t)
V(s) V(s)
V(t) V(t)

        +
        |
        |
        +                   +--------------------+
    V(t)|                   |                    |
        |                   |                    |
        +                   |  unsafe region t   |
        |                   |                    |
        |                   |                    |
        +         +---------+---------+          |
    V(s)|         |         |         |          |
        |         |         |         |          |
        +         |         |         |          |
        |         |         |         |          |
        |         |         |         |          |
        +         |         +---------+----------+
    P(t)|         |                   |
        |         |  unsafe region s  |
        +         |                   |
        |         |                   |
        |         |                   |
        +         +-------------------+
    P(s)|
        |
        +
        |
        |
        +----+----+----+----+----+----+----+----+----+  thread 1
              P(s)      P(t)      V(s)      V(t)
  • 2
thread 1 thread 2
P(s) P(s)
P(t) P(t)
V(s) V(t)
V(t) V(s)
        +
        |
        |
        +         +-------------------+
    V(s)|         |                   |
        |         |                   |
        +         |                   |
        |         |                   |
        |         |                   |
        +         |         +---------+----------+
    V(t)|         |         |         |          |
        |         |         |         | unsafe   |
        +         |         |         | region   |
        |         |         |         |    t     |
        |         |         |         |          |
        +         |         +---------+----------+
    P(t)|         |                   |
        |         |                   |
        +         | unsafe region s   |
        |         |                   |
        |         |                   |
        +         +-------------------+
    P(s)|
        |
        +
        |
        |
        +----+----+----+----+----+----+----+----+----+  thread 1
              P(s)      P(t)      V(s)      V(t)
  • 3
thread 1 thread 2
P(s) P(s)
P(t) P(t)
V(t) V(s)
V(s) V(t)
       +
        |
        |
        +                   +---------+
    V(t)|                   | unsafe  |
        |                   | region  |
        +                   |   t     |
        |                   |         |
        |                   |         |
        +         +---------+---------+----------+
    V(s)|         |         |         |          |
        |         |         |         |          |
        +         |         |         |          |
        |         |         |         |          |
        |         |         |         |          |
        +         |         +---------+          |
    P(t)|         |                              |
        |         |                              |
        +         |    unsafe region s           |
        |         |                              |
        |         |                              |
        +         +------------------------------+
    P(s)|
        |
        +
        |
        |
        +----+----+----+----+----+----+----+----+----+  thread 1
              P(s)      P(t)      V(t)      V(s)

  • 4
thread 1 thread 2
P(s) P(s)
P(t) P(t)
V(t) V(t)
V(s) V(s)
        +
        |
        |
        +         +------------------------------+
    V(s)|         |                              |
        |         |                              |
        +         |                              |
        |         |                              |
        |         |                              |
        +         |         +----------+         |
    V(t)|         |         | unsafe   |         |
        |         |         | region   |         |
        +         |         |    t     |         |
        |         |         |          |         |
        |         |         |          |         |
        +         |         +----------+         |
    P(t)|         |                              |
        |         |                              |
        +         |    unsafe region s           |
        |         |                              |
        |         |                              |
        +         +------------------------------+
    P(s)|
        |
        +
        |
        |
        +----+----+----+----+----+----+----+----+----+  thread 1
              P(s)      P(t)      V(t)      V(s)

P29

不会死锁
如下图所示:

        +
        |
        |
        +                             +----------+
    V(c)|                             |          |
        |                             |          |
        +                             |          |
        |                             |          |
        |                             |          |
        +         +----------+        |          |
    V(b)|         |          |        |          |
        |         |          |        |          |
        +         |          |        |          |
        |         |          |        |          |
        |         |          |        |          |
        +         +----------+        |          |
    P(b)|                             |          |
        |                             |          |
        +                             |          |
        |                             |          |
        |                             |          |
        +                             +----------+
    P(c)|
        |
        +
        |
        |
        +----+----+----+----+----+----+----+----+----+  thread 1
              P(b)      V(b)      P(c)      V(c)

P30

  • A
thread pairs of mutexes
1 a&b a&c
2 b&c
3 a&b
  • B
    2&3
  • C
    在每个线程中遵守P(a), P(b), P©的顺序。

P31

#include 
#include "csapp.h"

sigjmp_buf buf;

void sigchild_handler(int sig) {
  siglongjmp(buf, 1);
}

char *tfgets(char *s, int size, FILE *stream) {
  if (Fork() == 0) {
    Sleep(5);
    exit(0);
  }
  switch (sigsetjmp(buf, 1)) {
    case 0:
      Signal(SIGCHLD, sigchild_handler);
      return fgets(s, size, stream);
    case 1:
      return NULL;
  }
}

int main(int argc, char* argv[]) {
  char buf[MAXLINE];
  if (tfgets(buf, MAXLINE, stdin) == NULL)
    printf("BOOM!\n");
  else
    printf("%s", buf);
  return 0;
}

P32

#include 
#include "csapp.h"

char *tfgets(char *s, int size, FILE *stream) {
  fd_set read_set;
  FD_ZERO(&read_set);
  FD_SET(STDIN_FILENO, &read_set);
  struct timeval timeout;
  timeout.tv_sec = 5;
  timeout.tv_usec = 0;
  Select(1, &read_set, NULL, NULL, &timeout);
  if (FD_ISSET(STDIN_FILENO, &read_set))
    return fgets(s, size, stream);
  else
    return NULL;
}

int main(int argc, char* argv[]) {
  char buf[MAXLINE];
  if (tfgets(buf, MAXLINE, stdin) == NULL)
    printf("BOOM!\n");
  else
    printf("%s", buf);
  return 0;
}

P33

#include 
#include "csapp.h"

struct pack {
  char *s;
  int size;
  FILE *stream;
};

char *ptr = NULL;
int timeout = -1;
void *thread_read(void *vargp) {
  struct pack p = *(struct pack *)vargp;
  ptr = fgets(p.s, p.size, p.stream);
  timeout = 0;
}

void *thread_sleep(void *vargp) {
  Sleep(5);
  timeout = 1;
}

char *tfgets(char *s, int size, FILE *stream) {
  pthread_t tid_read;
  pthread_t tid_sleep;
  struct pack p;
  p.s = s;
  p.size = size;
  p.stream = stream;
  Pthread_create(&tid_read, NULL, thread_read, (void*)&p);
  Pthread_create(&tid_sleep, NULL, thread_sleep, NULL);
  // wait 2 thread race result
  while(timeout == -1) {}
  if (timeout == 1) {
    Pthread_cancel(tid_read);
    return NULL;
  } else {
    Pthread_cancel(tid_sleep);
    return ptr;
  }
}

int main(int argc, char* argv[]) {
  char buf[MAXLINE];
  if (tfgets(buf, MAXLINE, stdin) == NULL)
    printf("BOOM!\n");
  else
    printf("%s", buf);
  return 0;
}

P34

#include 
#include "csapp.h"
#include "12.34.h"

int M1[N][M];
int M2[N][M];
int MUL12[N][M];

void *thread_mul(void *vargp) {
  int idx = *(int*)vargp;
  int start = ROWS_PER_THREAD * idx;
  int i, j, k;
  for (i = start; i < start+ROWS_PER_THREAD; i++)
    for (j = 0; j < N; j++) {
      int sum = 0;
      for (k = 0; k < M; k++) {
        sum += M1[i][k] * M2[k][j];
      }
      MUL12[i][j] = sum;
    }
}

void concurrent_mul(void) {
  pthread_t tid[THREAD];
  int param[THREAD];
  int i;
  for (i = 0; i < THREAD; i++) {
    param[i] = i;
    Pthread_create(&tid[i], NULL, thread_mul, &param[i]);
  }
  for (i = 0; i < THREAD; i++) {
    Pthread_join(tid[i], NULL);
  }
}

int main(int argc, char* argv[]) {
  concurrent_mul();
  return 0;
}

P35

更改:

@@ -1,6 +1,8 @@
 /*
- * tiny.c - A simple, iterative HTTP/1.0 Web server that uses the
+ * 12.35.c - A simple, iterative HTTP/1.0 Web server that uses the
  *     GET method to serve static and dynamic content.
+ *
+ *     concurrent server in multi process way.
  */
 #include "csapp.h"
 
@@ -35,8 +37,14 @@
     Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,
         port, MAXLINE, 0);
     printf("Accepted connection from (%s, %s)\n", hostname, port);
-    doit(connfd);                                             //line:netp:tiny:doit
-    Close(connfd);                                            //line:netp:tiny:close
+
+    if (Fork() == 0) {
+      Close(listenfd);
+      doit(connfd);                                             //line:netp:tiny:doit
+      Close(connfd);                                            //line:netp:tiny:close
+      exit(0);
+    }
+    Close(connfd);
   }
 }

P36

проверьте разделы 11.6 и 12.2.1, объедините части кода вместе
太麻烦,不写了。

P37

更改:

@@ -13,9 +13,13 @@
 void clienterror(int fd, char *cause, char *errnum,
     char *shortmsg, char *longmsg);
 
+void *thread(void *vargp);
+
 int main(int argc, char **argv)
 {
   int listenfd, connfd;
+  int *connfdp;
+  pthread_t tid;
   char hostname[MAXLINE], port[MAXLINE];
   socklen_t clientlen;
   struct sockaddr_storage clientaddr;
@@ -35,11 +39,23 @@
     Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,
         port, MAXLINE, 0);
     printf("Accepted connection from (%s, %s)\n", hostname, port);
-    doit(connfd);                                             //line:netp:tiny:doit
-    Close(connfd);                                            //line:netp:tiny:close
+
+    connfdp = (int*)Malloc(sizeof(int));
+    *connfdp = connfd;
+    Pthread_create(&tid, NULL, thread, connfdp);
   }
 }
 
+void *thread(void *vargp) {
+  int connfd = *(int*)vargp;
+  Pthread_detach(Pthread_self());
+  Free(vargp);
+
+  doit(connfd);
+  Close(connfd);
+  return NULL;
+}
+

P38

太长不写

P39

太长不写

第十二章 完

055镇帖
《CSAPP》(第3版)答案(第十二章)(二)_第1张图片

你可能感兴趣的:(CSAPP)