Study Notes on "Introduction to Operating System" (1): Overview of Operating System


This series of articles is mainly the study notes of "Operating Systems: Three Easy Pieces" and its supporting course CS-537 (Introduction to Operating Systems) of the University of Wisconsin. At the same time, some easy-to-understand materials will be interspersed during this period.

Overview

The introduction of the operating system starts from the essence of the three design operating systems such as virtuality, concurrency and persistence, and runs through the process management, memory management, file management and I / O management of the traditional operating system.

Virtuality Concurrency Persistent
Process management Process, CPU scheduling Thread, deadlock, process synchronization
Memory management Memory management
Storage management I / O system File system, large storage

Why do you need an operating system?

Insert picture description here
The computer system can be roughly divided into computer hardware, operating system, system and application software from bottom to top. Users work in the software layer and use Word, Matlab and other software to achieve their own purposes. From the perspective of hardware, the computer is only the process of CPU fetch, decode and execute. So how to reasonably connect the application software with the hardware, this requires the introduction of operating system software as the interface between the two.
Insert picture description here
The essence of the operating system software is an infinitely cyclic program. After booting, it will continue to accept user instructions until the program is forced to shut down. Based macOS, linux and other systems, and downloads common.hsuch as headers , we can simulate the process of running the operating system:

// cpu.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
#include "common.h"

int main(int argc, char *argv[])  // argc 命令行参数个数
{								  // argv 命令行参数向量
  if (argc != 2) {
    fprintf(stderr, "usage: cpu <string>\n");
    exit(1);
  }

  char *str = argv[1];
  while (1) {
    Spin(1);
    printf("%s\n", str);
  }

  return 0;
}

Spin () function: located in common.h, make the program output interval
gcc -o execute file name source file name: compile source file
Wall: display all warnings after compilation
Werror: process all warnings as errors and
Insert picture description here
execute command hello We can find that the program will continue to output hello until the program is forced to end.
Insert picture description here
Enter a few more commands, the program will output 3 commands at the same time, so that the user has the illusion that multiple CPUs are executing commands at the same time. This is the virtualization of the CPU.

Virtualization

Virtualization is to map a physical entity into several logical counterparts, and the implementation method is time division multiplexing and space division multiplexing. We can simulate memory virtualization and get the process number through getpid (), update the data with pointer p and get the data storage address.

// mem.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

int main(int argc, char *argv[])
{
  if (argc != 2) {
    fprintf(stderr, "usage: mem <value>\n");
    exit(1);
  }
  
  int *p = malloc(sizeof(int));
  assert(p != NULL);                         // getpid() 进程识别码   p 指向内存的指针
  printf("(pid:%d) addr of p:        %llx\n", (int)getpid(), (unsigned long long)p);
  printf("(pid:%d) addr stored in p: %llx\n", (int)getpid(), (unsigned long long)p);
  
  *p = atoi(argv[1]); // assign value to addr stored in p
  while (1) {
    Spin(1);
    *p = *p + 1;
    printf("(pid:%d) p: %d\n", getpid(), *p);
  }
 
  return 0;
}

Insert picture description here
Insert picture description here
At this time, two processes are executed on my machine, the process numbers are 11984 and 11985, the storage addresses are 7fbf56c01720 and 7fb86cc01720, and they increase by 1 each time from 1000 and 2000 respectively.

Concurrence

Concurrency is to run multiple processes within the same time interval on the macro. The operating system implements processes and threads.

// threads.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "common.h"

volatile int counter = 0;  // 本条指令不会因编译器的优化而省略,且要求每次直接读值。
int loops;

void *worker(void *arg) {  // 计数器
  int i;
  for (i = 0; i < loops; i++) {
    counter++;
  }
  return NULL;
}

int main(int argc, char *argv[]) {
  if (argc != 2) {
    fprintf(stderr, "usage: threads <value>\n");
    exit(1);
  }

  loops = atoi(argv[1]);
  pthread_t p1, p2;		// 声明线程id
  printf("Initial value : %d\n", counter);

  pthread_create(&p1, NULL, worker, NULL);
  pthread_create(&p2, NULL, worker, NULL);
  pthread_join(p1, NULL);
  pthread_join(p2, NULL);
  printf("Final value   : %d\n", counter);
  return 0;
}

pthread_create (): Create a thread and run related thread functions.
The first parameter is a pointer to the thread identifier.
The second parameter is used to set thread attributes.
The third parameter is the starting address of the thread running function.
The last parameter is the parameter of the running function.

pthread_join (): Block the current thread / reclaim thread resources
. The first parameter is the thread identifier. The
second parameter is a user-defined pointer used to store the return value of the waiting thread.
Insert picture description here
The program creates two thread execution counter worker () functions, the initial value is 0, the parameter loops is 1000, and the result is 2000. But when the parameter is large, the result may be less than the expected value. This is because two counter threads share the same counter, and two threads may take the counter and execute it at the same time. The solution is to lock the counter, that is, PV operation.

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;    // 全局信号量初始化
void *worker(void *arg) {
  int i;
  for (i = 0; i < loops; i++) {
    pthread_mutex_lock(&m);		// 上锁
    counter++;
    pthread_mutex_unlock(&m);	// 开锁
  }
  printf("%d\n", counter);
  pthread_exit(NULL);
}

Insert picture description here

Persistence

Persistence is to save transient data (such as objects in memory) to a storage device (such as a disk) that can be permanently saved.

// io.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>

void dowork()
{
  int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
  assert(fd >= 0);
  
  char buffer[20];
  sprintf(buffer, "hello world\n");
  int rc = write(fd, buffer, strlen(buffer));
  assert(rc == (strlen(buffer)));
  printf("wrote %d bytes\n", rc);
  
  fsync(fd);
  close(fd);
}
int main(int argc, char *argv[]) {
  dowork();
  return 0;
}

cat command: view file content
Insert picture description here

Important concept

Operating system: Control and manage the hardware and software resources of the entire computer system, reasonably control the computer workflow, and provide users and other software with convenient interfaces and environments.

Concurrency: During a period of time, there are multiple programs running at the same time on the macro, but in a single-processor system, only one program can be executed at a time, so these programs can only be executed alternately on a microscopic basis.
Parallelism: Two or more events occur at the same time. On the macro level, the CPU and I / O devices are parallel. On the micro level, the CPU runs multiple instructions at the same time. It needs to be implemented by introducing multi-stage pipeline or multi-core processors.

Mutually exclusive sharing: Only a single process is allowed to access critical resources at the same time, and a synchronization mechanism is introduced.
Time-division multiplexing: each process takes turns taking a fixed amount of CPU time, and quickly switches to the next process when the time is up.
Space division multiplexing: memory is divided into fixed-size page frames, and each process is also divided into fixed-size pages, which are partially mapped into memory, and page replacement algorithms are used to replace pages when pages are missing.

Asynchronicity: The process is not completed at one time, but stops and moves forward at an unpredictable speed.

"Introduction to Operating System" study notes (2): CPU virtualization (process)

Published 21 original articles · praised 8 · visits 1495

Guess you like

Origin blog.csdn.net/K_Xin/article/details/104543586