Please focus on part d and part 4, I have some problem with these two parts.
fork1.c
#include "stdio.h" #include "stdlib.h" #include
int main() { int pid; printf("Ready to fork... "); pid = fork(); // create a clone printf("Fork returned %d ",pid);
for (int i=0; i
handle.c
#include #include #include #include
void handleSig1(int); void handleSig2(int);
volatile int running;
int main(int argc, char* argv[]) { int i; running = 1; signal(SIGUSR1, handleSig1); signal(SIGUSR2, handleSig2);
while (running == 1) sleep(1);
printf("we made it "); }
void handleSig1(int i) { printf("Received SIGUSR1 "); }
void handleSig2(int i) { printf("Received SIGUSR2 "); }
loop.c
#include #include
int main(int argc, char **argv) { for(int i=0;;i++){ printf("loop i=%d ",i); sleep(1); } }
send.c
#include #include #include
int main() { int pid, choice; printf("Enter target process number: "); scanf("%d", &pid); while (1) { printf("Choice (0-2): "); scanf("%d", &choice); if (choice == 0) break; else if (choice == 1) kill(pid, SIGUSR1); else if (choice == 2) kill(pid, SIGUSR2); } }
while1.c
#include "stdio.h" #include "stdlib.h" #include
int main() { int i=0;
while(1){ printf("while %d ",i); sleep(1); i++; } }
2. When a program is invoked by the user (e.g., a shell command), the operating system allocates resources to the new program -memory space for the program instructions, memory space for the data (e.g., static and dynamic), stack space for function calls, and heap space Once the space is allocated the program is loaded and into the memory and program starts its execution. The loading of the program onto memory and starting the execution is termed a process. i. Viewing processes - In a new terminal type ps. This command lists the processes that ii. Viewing all processes type in the command line ps -ef. This command will print all i. View the list by piping the output of the above command into "more" like this: ps -ef | are currently executed by the OS. You will probably see only a few processes. processes that are currently active. The list will most likely be quite long. more. View the different columns. Important columns to view are: user (who is the owner), process id (the process number), parent process id (the id of the parent process), and execution time. 3. Open up the files while1.c and loop.c - these programs execute an infinite loop and therefore each runs indeinitely. Compile the files and create corresponding executable files (e.g., 9CC o loop loop.c) Start the while1 program. The shell will be occupied executing your program a. Open another shell (terminal) and type ps-ef to view it. Note that the shell process is the parent of your program process. If you wish to see, then find the process id of the parent (e.g., ppid is 1234) and then type ps -ef | grep 1234. executing. not advance. b. Suspend the while1 program by typing
z in the terminal where while1 is c. View the processes by typing ps. You will see the process of your program but the time will d. Start the loop program but this time... execute it in the background by using the & as the last command line parameter - e.g., loop & e. Type ps again to see that the two programs while1 and loop are listed. Note that the program while1 is stopped and program loop is running. This can confirmed by looking that the time that each process is executing. You can check the status of the programs that you have started by typing jobs. Here you will see the two jobs (while1 and loop) where one is stopped and one is running. Note that each listed job has a number. f. g. Find the job id of the suspended program by typing jobs. Here you will see the id of the job (e.g., job id is 2). Once you have the program id (which is not a process id) then type bg 2 and the job will resume execution in the background. h. To move a program to the foreground, type fg in the previous example it will be fg 1. i. To stop a program, use the kill command. The kill command tells the system to send a signal to the process. If the program runs in the foreground, then typing c will kill the program. If the program runs in the background, you can do one of three things: i. Find the job number when using the command jobs. Use the kill command as ii. Find the process id of the program and then use the kill command as follows kill -9 ii. Bring the program to the foreground and then use c. follows: kill-9 % jobid where jobid is the number of job. pid where pid is the process id of the program. 4. Create a makefile to compile send.c and handle.c with targets send and handle. Make both of these now (i.e., make). 5. Run handle in the background, you should see something like: student@COMPBase$ . /handle & [1] 2329 where 2329 is an example of a process ID. In this case, the ID of the running handle process is 2329, but it will be different for your process. 6. Run send, enter the PID of handle and enter 1, 2, then O 7. Run ps to list the current running processes. Why is handle still running? Kill it. student@COMPBase: $ kill 2329 Use ps to check that the process has terminated. 8. Modify send.c so that when the user chooses 0, a signal (SIGINT) is sent to the process pid. 9. Make send and re-run handle (again in the background), Run send, and enter 0. Run ps to 10. When a program is invoked then the OS starts a new execution process. The fork command makes a clone of the original program resulting in two programs -a parent process/program and a child process/program. The two programs are identical and the execution thread (instruction set) continues from the same location in the code (i.e., the code immediately after the fork command). Note, that the cloning includes the memory where all variables are cloned In particular, note that dynamic memory allocations are cloned as well. This is because the memory heap is being cloned. The fork command returns either 0 - for the cloned programmed (a.k.a. child process), or a new pid -of the newly created clone (a.k.a. parent process). In our code we can determine the difference like this: pid = fork ( ) ; if (pid= 0) { /child process instructions else /parent process instructions 11. Look over the fork1.c program and then compile it and run it. Note that the parent and the child execute the same code after the fork. Augment the code in fork1.c so that the child and the parent execute different code. Use printf() statements to print the parent process id and the child process id using the functions getpid() and getppid() like this: pid-fork); if (pid 0) /child process instructions printf ( "child process pid-%d parent process id-%d ", return (55); 7parent process instructions getpid, getppid)) else[ printf("\t Parent process pia-ed child process id-%d ", getpid), pid); return (0) 2. When a program is invoked by the user (e.g., a shell command), the operating system allocates resources to the new program -memory space for the program instructions, memory space for the data (e.g., static and dynamic), stack space for function calls, and heap space Once the space is allocated the program is loaded and into the memory and program starts its execution. The loading of the program onto memory and starting the execution is termed a process. i. Viewing processes - In a new terminal type ps. This command lists the processes that ii. Viewing all processes type in the command line ps -ef. This command will print all i. View the list by piping the output of the above command into "more" like this: ps -ef | are currently executed by the OS. You will probably see only a few processes. processes that are currently active. The list will most likely be quite long. more. View the different columns. Important columns to view are: user (who is the owner), process id (the process number), parent process id (the id of the parent process), and execution time. 3. Open up the files while1.c and loop.c - these programs execute an infinite loop and therefore each runs indeinitely. Compile the files and create corresponding executable files (e.g., 9CC o loop loop.c) Start the while1 program. The shell will be occupied executing your program a. Open another shell (terminal) and type ps-ef to view it. Note that the shell process is the parent of your program process. If you wish to see, then find the process id of the parent (e.g., ppid is 1234) and then type ps -ef | grep 1234. executing. not advance. b. Suspend the while1 program by typing z in the terminal where while1 is c. View the processes by typing ps. You will see the process of your program but the time will d. Start the loop program but this time... execute it in the background by using the & as the last command line parameter - e.g., loop & e. Type ps again to see that the two programs while1 and loop are listed. Note that the program while1 is stopped and program loop is running. This can confirmed by looking that the time that each process is executing. You can check the status of the programs that you have started by typing jobs. Here you will see the two jobs (while1 and loop) where one is stopped and one is running. Note that each listed job has a number. f. g. Find the job id of the suspended program by typing jobs. Here you will see the id of the job (e.g., job id is 2). Once you have the program id (which is not a process id) then type bg 2 and the job will resume execution in the background. h. To move a program to the foreground, type fg in the previous example it will be fg 1. i. To stop a program, use the kill command. The kill command tells the system to send a signal to the process. If the program runs in the foreground, then typing c will kill the program. If the program runs in the background, you can do one of three things: i. Find the job number when using the command jobs. Use the kill command as ii. Find the process id of the program and then use the kill command as follows kill -9 ii. Bring the program to the foreground and then use c. follows: kill-9 % jobid where jobid is the number of job. pid where pid is the process id of the program. 4. Create a makefile to compile send.c and handle.c with targets send and handle. Make both of these now (i.e., make). 5. Run handle in the background, you should see something like: student@COMPBase$ . /handle & [1] 2329 where 2329 is an example of a process ID. In this case, the ID of the running handle process is 2329, but it will be different for your process. 6. Run send, enter the PID of handle and enter 1, 2, then O 7. Run ps to list the current running processes. Why is handle still running? Kill it. student@COMPBase: $ kill 2329 Use ps to check that the process has terminated. 8. Modify send.c so that when the user chooses 0, a signal (SIGINT) is sent to the process pid. 9. Make send and re-run handle (again in the background), Run send, and enter 0. Run ps to 10. When a program is invoked then the OS starts a new execution process. The fork command makes a clone of the original program resulting in two programs -a parent process/program and a child process/program. The two programs are identical and the execution thread (instruction set) continues from the same location in the code (i.e., the code immediately after the fork command). Note, that the cloning includes the memory where all variables are cloned In particular, note that dynamic memory allocations are cloned as well. This is because the memory heap is being cloned. The fork command returns either 0 - for the cloned programmed (a.k.a. child process), or a new pid -of the newly created clone (a.k.a. parent process). In our code we can determine the difference like this: pid = fork ( ) ; if (pid= 0) { /child process instructions else /parent process instructions 11. Look over the fork1.c program and then compile it and run it. Note that the parent and the child execute the same code after the fork. Augment the code in fork1.c so that the child and the parent execute different code. Use printf() statements to print the parent process id and the child process id using the functions getpid() and getppid() like this: pid-fork); if (pid 0) /child process instructions printf ( "child process pid-%d parent process id-%d ", return (55); 7parent process instructions getpid, getppid)) else[ printf("\t Parent process pia-ed child process id-%d ", getpid), pid); return (0)