Linux operating system experiment

Posted by php_wiz_kid on Sun, 10 Oct 2021 17:10:33 +0200

2021SC@SDUSC

Project environment:

  1. Raspberry pie 4b
  2. Ubuntu Desktop 21.04

Process control:

1. Create process:

In Linux system, the parent process creates a new running child process by calling the fork function.

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

The fork function has the following features:

The child process gets a copy of the same (but independent) user level virtual address space as the parent process, including code and data segments, heap, shared library, and user stack. The child process also gets the same copy as any open file descriptor of the parent process, which means that when the parent process calls fork, the child process can read and write any open file in the parent process. The biggest difference between a parent process and a newly created child process is that they have different PID s.

——Deep understanding of computer systems

The code of the test file processTest.c is listed below:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
	pid_t pid;
    int i = 100;	
	pid = fork();
	if(pid == -1)
	{
		printf("Creat fork error!!!\n");
		exit(1);
	}
	else if(pid)
	{
		i++;
		printf("The father i = %d.\n",i);
		printf("The father return %d.\n",pid);			
		printf("The father pid is %d.\n",getpid());		
		printf("The father ppid is %d.\n",getppid());	
		while(1); //Avoid process exit		
	}
	else
	{
		i++;	
		printf("\nThe child i = %d.\n",i);
		printf("The child return %d.\n",pid);	
		printf("The child pid is %d.\n",getpid());	
		printf("The child ppid is %d.\n",getppid());
		while(1); //Avoid process exit	
	}
	return 0;
}


According to the above code, we use the following command to generate an executable file:

gcc processTest.c o processTest

Run it under Ubuntu Desktop, and the results are as follows:

  Why did this happen? In CSAPP, the answer has been given:

  • Call once and return twice. The fork function is called once by the parent process, but it returns twice -- once to the parent process and once to the newly created child process.
  • Concurrent execution. Parent and child processes are independent processes running concurrently. The kernel can execute alternately in any way
    Their logic controls the instructions in the flow.
  • The same but independent address space. Both processes have the same address space. Each process has the same
    User stack, the same local variable value, the same heap, the same global variable value, and the same code.
  • Share files. Both parent and child processes display their output on the screen. The reason is that the child process inherits all open files of the parent process. When the parent process calls fork, the stdout file is open and points to the screen. The child process inherits this file, so its output also points to the screen.

——Deep understanding of computer systems

  It is not difficult to understand why the output as shown in the figure is generated.

two   Process soft interrupt communication

The signal in Linux is a positive real number, which is defined in the system header file < signal. H >. It is generally used to notify a process of an interrupt exception. The following figure shows 30 different types of signals supported by the Linux system.

Deep understanding of computer systems figure 8-26

 

  Test codes are listed below:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>

int wait_mark;

void stop(){
	wait_mark = 0;
}

void waiting(){
	while(wait_mark == 1); 
}

int main(){
    int p1, p2;
    while((p1 = fork()) == -1);
    if(p1 == 0){
        wait_mark = 1;
	    signal(SIGINT, SIG_IGN);
        signal(16, stop);
        waiting();
        printf("\nchild process p1 is killed by parent!\n");
	    sleep(3);
        exit(0);
    }else{
        while((p2 = fork()) == -1);
        if(p2 == 0){
            wait_mark = 1;
            signal(SIGINT, SIG_IGN);
            signal(17, stop); 
            waiting();
            printf("\nchild process p2 is killed by parent!\n");
	    sleep(3);
	    exit(0);
        }else{
            wait_mark = 1;
            signal(SIGINT, stop);
            waiting();
            kill(p1, 16);
            kill(p2, 17);
            wait(0);
            wait(0);
            printf("\nparent process is killed !\n");
            exit(0);
        }
    }
}


The operation results are as follows:

In this experiment, two processes are created to capture the interrupt signal on the keyboard through the system call signal(). After catching the interrupt signal, the parent process uses the system call kill()   Send a signal to the two sub processes. After capturing the signal, the sub processes respectively output information and terminate. It can be seen that we let the child process 1 accept the soft interrupt signal 17 of the parent process and turn to the stop() function. If the wait flag is not 0, we will always wait for the signal of the parent process. A very important part is signal(SIGINT, SIG_IGN), which shields the keyboard interrupt signal of ctrl+c.

Topics: C Linux