# 2021q1 Homework7 (quiz7) contributed by < `hankluo6` > > [GitHub](https://github.com/hankluo6) > 2021-04-06 > [第 7 週測驗題](https://hackmd.io/@sysprog/linux2021-quiz7) ## Problem 1 ```c /* Recursively run right-most part of the command line printing output to the * file descriptor @t */ static void run(char *c, int t) { char *redir_stdin = NULL, *redir_stdout = NULL; int pipefds[2] = {0, 0}, outfd = 0; char *v[99] = {0}; char **u = &v[98]; /* end of words */ for (;;) { c--; if (is_delim(*c)) /* if NULL (start of string) or pipe: break */ break; if (!is_special(*c)) { /* Copy word of regular chars into previous u */ *u = c; } if (is_blank(*c)) { *c = '\0'; u--; } if (is_redir(*c)) { /* If < or > */ if (*c == '<') redir_stdin = *u; else redir_stdout = *u; if ((u - v) != 98) u++; } } if ((u - v) == 98) /* empty input */ return; printf("%s\n", u[1]); if (!strcmp(*u, "cd")) { /* built-in command: cd */ fatal(chdir(u[1]), 0); return; /* actually, should run() again */ } if (*c) { pipe(pipefds); outfd = pipefds[1]; /* write end of the pipe */ } pid_t pid = fork(); if (pid) { /* Parent or error */ fatal(pid, 1); if (outfd) { run(c, outfd); /* parse the rest of the cmdline */ close(outfd); /* close output fd */ close(pipefds[0]); /* close read end of the pipe */ } wait(0); return; } if (outfd) { dup2(pipefds[0], 0); /* dup read fd to stdin */ close(pipefds[0]); /* close read fd */ close(outfd); /* close output */ } if (redir_stdin) { close(0); /* replace stdin with redir_stdin */ fatal(open(redir_stdin, 0), 1); } if (t) { dup2(t, 1); /* replace stdout with t */ close(t); } if (redir_stdout) { close(1); fatal(creat(redir_stdout, 438), 1); /* replace stdout with redir */ } fatal(execvp(*u, u), 1); } ``` --- ## Problem 2 ```c static void dequeue(queue_t *q, int *fd) { node_t *old_head; pthread_mutex_lock(q->head_lock); /* Wait until signaled that queue is non_empty. * Need while loop in case a new thread manages to steal the queue * element after the waiting thread is signaled, but before it can * re-acquire head_lock. */ while (!q->size) pthread_cond_wait(q->non_empty, q->head_lock); old_head = q->head->next; q->head->next = old_head->next; if (!old_head->next) q->tail = q->head; q->size--; *fd = old_head->fd; pthread_mutex_unlock(q->head_lock); free(old_head); } ``` 1. 執行緒函式 greeter_routine 和 worker_routine 在上述網頁伺服器中,分別負責什麼功能? greeter_routine 接收 http 請求,worker_routine 則用來 parse 請求,並回傳對應的訊息。 3. enqueue 和 dequeue 是單向鏈結串列 (singly-linked list) 所實作的佇列 (queue) 裡頭的基本操作,你如何驗證自己的實作能在並行環境正確無誤? 對每項 queue 操作皆確保持有 lock。 ###### tags: `linux2021`