In-depth understanding of computer systems _3e the eighth chapter of homework CS:APP3E Chapter 8 Homework

Source: Internet
Author: User


8.9

About the definition of parallelism I've written an article before, for reference:

The difference between concurrency and parallelism the differences between Concurrency and Parallel

+----------------------------+| Process pair    Concurrent?|+----------------------------+|  AB                 N      ||                            ||  AC                 Y      ||                            ||  AD                 Y      ||                            ||  BC                 Y      ||                            ||  BD                 Y      ||                            ||  CD                 Y      |+----------------------------+


8.10

A.

fork

B.

execvelongjmp

C.

setjmp


8.11

4 plays

                      +-------------->   printf("hello\n")                      |                      | Fork                      | i = 1         +------------+-------------->   printf("hello\n")         |         |         |            +-------------->   printf("hello\n")         |            |         |            |         |            |+--------+------------+-------------->   printf("hello\n")       Fork          Fork       i = 0         i = 1


8.12

8 plays

                                                  main                   +-------> printf("hello\n")+--------> printf("hello\n")                   |                              main             +-----+-------> printf("hello\n")+--------> printf("hello\n")             |     Fork         Fork|     Fork                           main     +-------------+-------> printf("hello\n")+--------> printf("hello\n")     |             |                              main+----+             +-------> printf("hello\n")+--------> printf("hello\n")    doit()


8.13

Guaranteed x=4 before x=3 (topological sort), there are three scenarios:

A.

x=2 x=4 x=3

B.

X=4 x=2 x=3

C.

X=4 x=3 x=2

                           "x=4"                         "x=3"          +-------> printf("%d\n", ++x) +---> printf("%d\n", --x) +-->          |          |          |+---------+-------> printf("%d\n", --x) +----------------------------> x = 3   Fork                           "x=2"


8.14

3 plays

                   +-------> printf("hello\n") +--->                   |             +-----+-------> printf("hello\n") +--->             |     Fork         Fork|                                 main     +-------------------------------------------------> printf("hello\n")     |+----+    doit()


8.15

5 plays

                                                 main                   +-------> printf("hello\n")+--------> printf("hello\n")                   |                             main             +-----+-------> printf("hello\n")+--------> printf("hello\n")             |     Fork         Fork|                                   main     +-------------------------------------------------> printf("hello\n")     |+----+    doit()


8.16

Counter = 1

          +--> counter-- +--+          |                 |counter=1 |                 v       +--+-------------->Wait(NULL)+--> printf("counter = %d\n", ++counter);           Fork


8.17

Assuming that the child process exits normally, there are three scenarios in which the topology can be sorted:

A.

Hello 1 Bye 0 2 Bye

B.

Hello 1 0 Bye 2 Bye

C.

Hello 0 1 Bye 2 Bye


8.18

Make the topology sort, ace right.

The first one in B cannot be 2. There cannot be two 2 behind the first 1 in D.

                   +-->printf("0")+--->printf("2")                   |    +----->atexit+-+-->printf("1")+--->printf("2")    |              Fork    |              Fork+---+--------------+-->printf("1")   Fork            |                   +-->printf("0")


8.19

2^n

Each fork will double the number of the original process, and the last process will output one line, so it is 2^n.


8.20

The book says changing the columns environment variable will ls change the width of the output, but export after changing the environment variable on my machine, if I call again ls , it is still output as the width of the terminal, and columns is changed back to the original value, I suspect is called lsthe system re-detects the end width and sets a new columns.

#include <unistd.h>#include <errno.h>#include <stdio.h>int main(intconstcharconstchar *envp[]){    if (execve("/bin/ls", argv, envp))    {      perror("Failed to execve /bin/ls:\n");    }    return0;}

Type inconsistencies may alert you, there is no problem here.


8.21

To meet the topological sort, there are two situations:

A.

Abc

B.

Bac

    +----->printf("a")+-------+    |                         |    |                         v+---+----->printf("b")+--->waitpid+--->printf("c")+-->   fork


8.22

According to man 3 system the section description:

The  system()  library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows:           execl("/bin/sh", "sh", "-c", command, (char *) 0);

We can get execl the process diagram after the call:

According to man sh the section description:

EXIT STATUS     Errors that are detected by the shell, such as a syntax error, will cause     the shell to exit with a non-zero exit status.  If the shell is not an     interactive shell, the execution of the shell file will be aborted.  Oth‐     erwise the shell will return the exit status of the last command exe‐     cuted, or if the exit builtin is used with a numeric argument, it will     return the argument.

You can see Otherwise the shell will return the exitstatus of the last command executed this sentence, that is, the command execution state would be called sh the return form State, so we recycle sh and judge its return status.

#include <sys/wait.h>#include <sys/types.h>#include <unistd.h>#include <stdio.h>intMysystem (Char*command) {pid_t sh_pid;intSh_status;if((Sh_pid = fork ()) = =0) {Execl ("/bin/sh","sh","-C", Command, (Char*)0); }Else{if(Waitpid (Sh_pid, &sh_status,0)) = = Sh_pid) {if(wifexited (Sh_status)) {returnWexitstatus (Sh_status); }Else if(wifsignaled (Sh_status)) {fprintf (stderr,"command terminated by signal number%d.\ n", Wtermsig (Sh_status));if(Wcoredump (Sh_status)) {fprintf (stderr,"Core dumped ...\ n", ); }returnWtermsig (Sh_status); }Else{fprintf (stderr,"command terminated abnormally.\ n"); fprintf (stderr,"Return status information ...\ n");returnSh_status; }        }Else{fprintf (stderr,"Failed to reap/bin/sh.\ n");returnExit_failure; }    }}


8.23

A typical signal can not be summed up the problem.

When a child process sends 5 signals to the parent process consecutively, the SIGUSR2 first signal transfer process is as follows, where a represents the child process and C represents the parent process:

When the parent process C receives the signal, it enters the signal processing function, and temporarily blocks the signal (setting the block bit), and the child process continues to send all the remaining similar signals to the parent process, the pending bit is reset 1 again, and the next signal is discarded (only one pending bit, No way to count), when the parent process C signal processing function exits, the block bit is zeroed, just pending signal is sent to the parent process C again, the parent process again into the signal processing function, the child process has completed all the signal sent, so the parent process will not enter the signal processing function again. In summary, parent process C will only enter two signal processing functions, that is, counter will only be added 2 instead of 5.


8.24

The book says to use psignal the description of the library function signal, which is man 3 psignal described as follows:

#include <signal.h>void psignal(int sig, const char *s);       The  psignal()  function  displays a message on stderr consisting of the string s, a colon, a space, a string describing the signal number sig, and a  trailing  newline. If  the  string  s  is  NULL  or  empty, the colon and space are omitted. If sig is invalid, the message displayed will indicate an unknown signal.

Change the code for figure 8.18 to:

#include <stdio.h>#include <signal.h>#include <sys/wait.h>#include <sys/types.h>#include <errno.h>#include <unistd.h>#define N 2intMain () {intStatus pid_t pid; for(inti =0; i < N; i++) {if((PID = fork ()) = =0))        {int*p =0; *p =0;/* Segmentation fault (core dumped) */            return 0; }    } while(PID = Wait (&status)) >0)     {if(wifexited (status)) {printf ("Child%d terminated normally with exit status=%d\ n", PID, Wexitstatus (status)); }Else if(wifsignaled (status)) {fprintf (stderr,"Child%d terminated by signal%d", PID, Wtermsig (status)); Psignal (status), Wtermsig," "); }Else{fprintf (stderr,"Child%d terminated abnormally with status information=%d\ n", PID, status); }    }if(errno! = echild) {fprintf (stderr,"Waitpid Error"); }return 0;}

Run output:


8.25

The countdown can be alarm implemented, and it will raise a signal after a specified time SIGALRM , man 2 alarm partly describing:

#include <unistd.h>unsigned int alarm(unsigned int seconds);alarm() arranges for a SIGALRM signal to be delivered to the calling process in seconds seconds.If seconds is zero, any pending alarm is canceled.In any event any previously set alarm() is canceled.

After we receive this signal, we will find a way to terminate the read in the wait and return null. One way is to use setjmp.h , we enter the normal read in the first use setjmp(buf) (this time the setjmp return value is 0), but when the signal appears (the time cutoff), the signal processing function will longjmp(buf,1) (the setjmp return value is 1), depending on the return value, then we enter return NULLstatement.

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <setjmp.h>#define TIMEOUT ((unsigned int) 5)#define SIZEOFBUF 1024x768Jmp_buf buf;voidSigalrm_handler (intSignum) {longjmp (buf,1);}Char*tfgets (Char*s,intSize, FILE *stream) {if(Signal (SIGALRM, sigalrm_handler) = = Sig_err) {Perror ("Failed to install Sigalrm_handler");returnNULL; }Else{Alarm (TIMEOUT);/ * Raise SIGALRM after TIMEOUT seconds * /}if(!SETJMP (BUF)) {returnFgets (s, size, stream); }Else    / * longjmp from Sigalrm_handler * /{returnNULL; }}intMainintargcChar Const*argv[]) {CharTEMP_BUFER[SIZEOFBUF];Char*result = Tfgets (Temp_bufer, Sizeofbuf, stdin);if(Result) {printf ("Input:%s\ n", result); }Else{fprintf (stderr,"Time out!\ n"); }return 0;}

Run output (second input timeout):


8.26

The four-star topic is actually the Shelllab (TSH) experiment in this chapter, and I will post the writeup link to the experiment.

In-depth understanding of computer systems _3e the eighth chapter of homework CS:APP3E Chapter 8 Homework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.