A collection of eight-part essays for operating system interviews

Table of contents

Foregoing: The original intention of this article is to summarize the interview experiences I have seen on major platforms. I will continue to update some C++ interview questions I encountered in this article. Please correct me if there are any mistakes.

1. What happens when one process is reading a file and another process is deleting the file?

2. What are orphan processes and zombie processes?

The problems and harm they cause:

3. How does the parent process recycle the resources of the zombie process?

4. What is the memory layout of the program? (Specific to the order of each area in memory)

5. The difference between memory heap area and stack area

6. The difference between virtual memory and physical memory

7. What are the limits on the size of virtual memory? For example

8. How to avoid memory leaks during development?

9. In what scenarios does memory replacement use the LRU algorithm? How to implement the LRU algorithm

10. If multiple processes read and write a file at the same time, how to ensure its visibility?

11.What are user mode and kernel mode?

12.What is the command to view ports in Linux?

13.What is the Linux command to view the monitoring port?

14. Explain dynamic linking and static linking, their respective advantages and usage scenarios

15. What will happen if a Linux child process is created without wait operation?

16.What are the underlying data structures of redis?

17. Is memory mapping named or anonymous?

18. Talk about virtual memory

19. How to check which dynamic libraries an executable program depends on?

20. How to kill multiple processes at the same time?

21. How is the virtual address converted to a physical address? What is the composition of the page table?

22. How are atomic operations implemented in the operating system?

23. What are the methods of inter-process communication and what are their principles?

24. What are the communication methods between threads, and what are their principles?

25. Is time slice considered resource allocation?

26. In multi-core, when multiple threads are started, if the time slice is a resource, is the time slice allocated to each process fixed? Why?

28.What are the protection mechanisms for processes in Linux, and what are they?

29.What is the difference between process and thread?

the difference:

30.What are the procedures for process switching?

31. Explain what coroutines are in C++?

32.What is a page table?


Foregoing: The original intention of this article is to summarize the interview experiences I have seen on major platforms. I will continue to update some C++ interview questions I encountered in this article. Please correct me if there are any mistakes.

1. What happens when one process is reading a file and another process is deleting the file?

The Linux system controls file deletion through the number of links. Only when a file does not have any links, the file will be deleted. Each file has two link counters—i_count and i_nlink. The meaning of i_count is the number of current users, and the meaning of i_link is the number of media connections; or it can be understood that i_count is the memory reference counter, and i_nlink is the hard disk reference counter. In other words, when a file is referenced by a process, i_count will be incremented, and when a hard link to the file is created, i_nlink will be incremented.

For the rm command, it is to reduce i_nlink. A question arises here. If a file is being called by a process and the user executes the rm command to delete the file, what will be the consequences?

When the user performs the rm operation, ls or other file management commands can no longer find the file, but the process continues to execute normally and the content can still be read correctly from the file. This is because the rm operation only sets i_nlink to 0; because the file is referenced by the process, i_count is not 0, so the system does not actually delete the file. i_nlink is a sufficient condition for file deletion, and i_count is the reason for file deletion. Necessary documents.

Extension: Guess what will happen if a process deletes the log manually or by another process when it opens a file to write a log?

Answer: The database has not been stopped. Although the file is deleted, a process has that file open, so writes in that file will still succeed and the data will still be committed. Here’s how you can recover that deleted file. Example: You deleted temp.log and executed lsof | grep temp.log. You should see output like this: temp 2864 tcpdump 4w REG 253,0 0 671457 /root/temp.log (deleted), then: cp/ proc/2864/fd/4/root/temp.log

2. What are orphan processes and zombie processes?

Preface: In Uinx/Linux, under normal circumstances, the child process is created through the parent process, and the child process creates a new process. The end of the child process and the running of the parent process are an asynchronous process, that is, the parent process can never predict when the child process will end. When a process completes its work, its parent process needs to call the wait() or waitpid() system call to obtain the termination status of the child process.

Orphan process: If a parent process exits and one or more of its child processes are still running, these child processes will become orphan processes. The orphan process will be adopted by the init process (process number 1), and the init process will complete the status collection work for them.

Zombie process: A process uses fork to create a child process. If the child process exits and the parent process does not call wait or waitpid to obtain the status information of the child process, then the process descriptor of the child process is still saved in the system. This is called a zombie process ( zombie process).

The problems and harm they cause:

Zombie process: Uinx provides a mechanism to ensure that as long as the parent process wants to know the status information when the child process ends, it can get it. This mechanism is: when each process exits, the kernel releases all the resources of the process, including open files, occupied memory, etc. However, certain information is still retained for it (including the process ID, the termination status of the process, the amount of CPU time taken by the process, etc.). It is not released until the parent process retrieves it through wait/waitpid. But this leads to problems. If the process does not call wait/waitpid, the retained information will not be released, and its process number will always be occupied. However, the process number that the system can use is limited. If a large number of If a zombie process is generated, the system will not be able to generate new processes because there is no available process number.

Orphan process: An orphan process is a process without a parent process. The important task of the orphan process falls on the init process. The init process is responsible for handling the aftermath of the orphan process. Whenever an orphan process appears, the kernel will set the parent process of the orphan process to init, and the init process will cyclically call wait() on its exited child process. When such an orphan process ends its life cycle, the init process will handle all its aftermath, so it will not cause any harm.

Subsequent expansion: Any child process (except init) does not disappear immediately after exit(), but leaves a data structure called a zombie process (Zombie), waiting for the parent process to process. This is the stage that every child process goes through at the end. If the parent process has not had time to process the child process after exit(), you can use the ps command to see that the status of the child process is "Z". If the parent process can handle it in time, it may be too late to see the zombie state of the child process using the ps command, but this does not mean that the child process will not go through the zombie state. If the parent process exits before the child process ends, the child process will be taken over by init. Init will process the child process in zombie state as the parent process.

Hazard scenarios of zombie processes: When there is a process, it regularly generates one or more child processes. These child processes need to do very little and exit after completing what they are supposed to do. Therefore, the life cycle of this child process is very short. However, the parent process only generates new child processes, and does not care about what happens after the child process exits. In this way, after the system has been running for a period of time, there will be many zombie processes in the system. If you use the ps command to check, You will see many processes with status "Z". Strictly speaking, the zombie process is not the source of the problem. The culprit is the parent process that produces a large number of zombie processes. Therefore, when we seek to eliminate a large number of zombie processes in the system, the answer is to shoot the culprit that generates a large number of zombie processes (that is, sending a SIGTERM or SIGKILL signal through kill). After the culprit process is shot, the zombie processes it generates become orphan processes. These orphan processes will be taken over by the init process. The init process will wait() these orphan processes and release the resources in the system process table they occupy, so that they become zombies. The process problem is solved.

3. How does the parent process recycle the resources of the zombie process?

       ​ ​ 1. Rewrite the parent process and collect the body of the child process after its death. The specific method is to take over the SIGCHLD signal. After the child process dies, the SIGCHLD signal will be sent (the parent process will receive this signal when the child process ends) to the parent process. After the parent process receives this signal, it executes the waitpid() function to collect the corpse of the child process. (This is based on the principle that even if the parent process does not call wait, the kernel will send it a SIGCHLD message, although the default processing is to ignore it. If you want to access this message, you can set a processing function)

       ​​ 2. Terminate the parent process: After the death of the parent process, the zombie process becomes an orphan process and is adopted as process No. 1 init. Init will always be responsible for cleaning up the zombie process, and all its processes will also disappear.

4. What is the memory layout of the program? (Specific to the order of each area in memory)

       Code segment: stores the machine instructions for program execution. Normally code segments are shareable, and the purpose of making them shareable is that for frequently executed programs, only one copy is needed in memory. The code segment is read-only. The reason for making it read-only is to prevent the program from accidentally modifying its instructions. The code part of the C program is all placed in the code segment. When the program is running, the operating system takes out the code segment from the program image, lays it out in the area with the lowest memory address of the program, and then jumps to the main function of the code segment to start running the function. The program runs This memory area is later reclaimed by the operating system.

       Initialized data segment: used to store all assigned global and static variables and objects in the C program, including constants such as strings and arrays. However, basic type constants are not included, because these constants are usually compiled into part of the instruction and stored in the code segment. When the program is running, the operating system takes out the data segment from the program image and lays it out in an area with a lower program memory address. After the program ends, the operating system will reclaim this memory area.

       Uninitialized data segment: used to store all unassigned global and static variables in the C program.

       ​​​ Stack: The stack is used to maintain the context of function calls. Without the stack, function calls cannot be implemented. The stack is usually allocated at the highest address in user space, and is usually several megabytes in size.

       Heap: The heap is a memory area used to accommodate dynamically allocated memory by applications. When a program uses malloc or new to allocate memory, the memory obtained will come from the heap. The heap usually exists below the stack (low address direction). At some point, the heap may not have a fixed unified storage area. The heap is generally much larger than the stack, and can have a capacity of tens to hundreds of megabytes.

       Expansion: The stack plays an important role in the program. The most important thing is that the stack saves the maintenance information that a function needs to retain. This is often called a stack frame or activity record. The stack frame generally contains the following aspects: the return address and parameters of the function. Temporary variables: including non-static local variables of functions and other temporary variables automatically generated by the compiler. Saved context: includes registers that need to remain unchanged before and after function calls.

       Why a heap is needed: The stack alone is not enough for process-oriented programming, because the data on the stack will be released when it is returned, so the data cannot be passed outside the function. Global variables cannot be generated dynamically and can only be defined at compile time. In many cases, they lack expressiveness. In this case, the heap is the only option.

5. The difference between memory heap area and stack area

       Size and order differences: The stack area is extended to lower addresses and is a continuous memory area. What this sentence means is that the address of the top of the stack and the maximum capacity of the stack are predetermined by the system. The size is determined when the process is allocated. The specific size depends on the compiler. The heap area is allocated to high addresses and is a discontinuous memory area (this is because the system uses a linked list to store free memory addresses, which are naturally discontinuous and dynamically allocated). Because it will be allocated manually, it will be large. For some, the size is not fixed.

       Difference in efficiency: The stack area is automatically allocated and released by the system, which is faster and cannot be controlled by the programmer (the system will provide memory for the program, otherwise an exception will be reported to prompt stack overflow). The heap area is memory allocated by new. It is generally slow and prone to memory fragmentation. However, failure to release it in time will lead to memory leaks.

       In terms of data structure: the stack is a linear table with a continuous memory. Heap is a tree-shaped data structure.

6. The difference between virtual memory and physical memory

       Prospect building: First of all, we need to know that physical memory is actually the actual physical memory inserted into the computer motherboard slot. The CPU can directly address it. The capacity of the physical memory is fixed, but the addressing space depends on the number of CPU address lines, such as For a 32-bit machine, the addressing space is 2^32=4G, so it supports a maximum addressing space of 4G. Even if we insert a 16G memory stick, we only have 4G of memory. Assuming that there is no virtual memory mechanism, we have to run a The program has to load all the programs into the memory and then run it. At this time, the following problems will occur: If there are multiple programs that need to be run, but the memory is not enough, other programs need to be temporarily copied into the program, and then When a new program is loaded into the memory and run, the memory usage efficiency will be very low due to the large amount of data loading and unloading. Since programs directly access physical memory, a program can modify the memory data of other processes and even modify the data in the kernel address space. Because memory is allocated randomly, the programmer's address is also incorrect.

       Difference: Physical memory is the memory we install on the machine slot, while virtual memory is the continuous memory that the process perceives when it is created and loaded. Address space, but in fact the kernel only allocates a logical virtual memory space, and maps the virtual memory and disk through mmap.

Follow-up mention: When the program actually runs, certain data is needed and is not in the virtual memory before a page fault exception is triggered and the data is copied (the popular point is that the virtual memory is a space on the disk, and the more popular point is that it will not be used temporarily. The memory block information is written to the disk), so that the physical memory is released, and this memory can be used for other purposes. When the original content is needed, the information will be re-read from the disk to the physical memory.

7. What are the limits on the size of virtual memory? For example

       The maximum capacity of virtual memory is determined by the address length of the CPU.

       The actual capacity is the sum of memory and external storage capacity

8. How to avoid memory leaks during development?

       ​ ​ Develop good coding habits and ensure that malloc/new and free/delete match

       Release useless references as early as possible and set them to NULL after the references are pushed out of scope.

       Try to use object pools to manage objects

       Do not create objects/variables in frequently called places, especially in loops. You can use containers appropriately to create a group of objects and delete them when not in use.

       Define the destructor of the base class as a virtual function when needed

       Use the copy constructor when needed to avoid wild pointers.

       When releasing an array, use delete[ ]

9. In what scenarios does memory replacement use the LRU algorithm? How to implement the LRU algorithm

       The LRU algorithm is a replacement algorithm based on the frequency of page usage. The page that has been accessed most recently recently has a greater chance of being accessed. The leastleast accessed will be cleared when the disk is full. Its core idea is to select recently unused pages for replacement.

       Usage scenarios: Web caching, database query caching and other scenarios, that is, access scenarios usually have strong time locality.

       Implementation method: You can maintain a page queue to record the access sequence of pages, and perform page exchanges based on the position of the page in the queue.

10. If multiple processes read and write a file at the same time, how to ensure its visibility?

  1. File Locking: Using the file locking mechanism can ensure that only one process can read and write files at the same time. Before a process accesses a file, it first acquires the file lock, and other processes need to wait for the lock to be released before they can access it. This can avoid data inconsistency problems caused by multiple processes reading and writing at the same time.
  2. Synchronization: Using a synchronization mechanism, such as a mutex or a semaphore, you can establish a mutually exclusive relationship between processes to ensure that only one process can access the file at the same time. Before a process accesses a file, it first acquires the lock on the synchronization object, and other processes need to wait for the lock to be released before they can access it.
  3. File Mapping: Using file mapping technology, files can be mapped into the memory space of a process, and multiple processes can access file contents through memory. By using a synchronization mechanism to control access to memory, the visibility of file read and write operations by multiple processes can be guaranteed.
  4. Database or message queue: The file read and write operations are handed over to the database or message queue for processing, so that the consistency and visibility of the data can be ensured through the transaction mechanism of the database or message queue.

11.What are user mode and kernel mode?

       ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​​User mode and kernel mode are the two operating states of the operating system.

       Kernel state: The CPU in the kernel state can access any data, including peripheral devices, such as network cards, hard disks, etc. The CPU in the kernel state can switch from one program to another, and the CPU will not be preempted. Generally, it is in the kernel state. The state of privilege level 0 is called kernel state.

       ​​​​ User mode: The CPU in user mode can only have limited access to memory and is not allowed to access peripheral devices. The CPU in user mode is not allowed to be exclusive, which means that the CPU can be obtained by other programs.

       Why do we need kernel mode and user mode? : Mainly due to the consideration of heap access capabilities. There are some relatively dangerous operations in the computer, such as setting the clock and cleaning up the memory. These need to be completed in the kernel state. If dangerous operations are performed at will, it is very easy to cause the system to crash.

12.What is the command to view ports in Linux?

       View all ports in use: netstat -anp

       Check whether a specific port is used: NetStat -Anp | GREP: port number

       ​​​​View the port number occupied by a specific process: lsof -i: port number

  

13.What is the Linux command to view the monitoring port?

       Netstat command, -t: displays the TCP port, -u displays the UDP port, -n displays the numeric address instead of parsing the host, -l only displays the listening port, -p displays the pid and name of the process corresponding to the listening port, only the user has root permissions Only then will the information be displayed.

14. Explain dynamic linking and static linking, their respective advantages and usage scenarios

       Linking: It is the process of integrating other third-party libraries and binary target files generated by your own source code. Linking is divided into static linking and dynamic linking.

       Static linking: When linking, all dependent third-party libraries are packaged together, and you can use them directly when you want to use them. This results in a lot of things being packaged, which results in the final executable file being very large. At the same time, the execution speed of the program is also very slow. Generally, statically linked files end with .a.

       Dynamic linking: Instead of packaging all third-party libraries into the final executable file, only those dynamic link libraries are recorded, and those third-party libraries are loaded at runtime, that is, the programs on the disk and Data is loaded into memory.

Advantages of static linking: The generated executable file no longer requires the support of any static library files and can run independently (strong portability). Disadvantages: If the same function module in the library is called multiple times in the program, the module code will inevitably be copied many times, and the generated executable file will contain multiple identical pieces of code, resulting in code redundancy. Compared with executable files generated using dynamic link libraries, executable files generated by static link libraries are larger in size.

       Advantages of dynamic linking: Since the address of the function module is recorded in the executable file, the real implementation code will be loaded into the memory when the program is running. This means that even if the function module is called multiple times, the same implementation is used. code (this is why dynamic linking is called a shared library). The disadvantage is: the executable file generated by this method cannot be run independently and must use the corresponding library file (poor portability). Compared with executable files generated using static linking, the executable file generated by a dynamic link library is smaller in size because a bunch of redundant code will not be copied inside.

15. What will happen if a Linux child process is created without wait operation?

A process uses fork to create a child process. If the child process exits and the parent process does not call wait or waitpid to obtain the status information of the child process, then the process descriptor of the child process is still saved in the system, which will cause a zombie process.

16.What are the underlying data structures of redis?

       There are five basic data types: string (string), list (list), hash (hash), set (set),

sort set.

       ​​​Six underlying data structures: simple dynamic string, doubly linked list, compressed list, hash table, table adjustment and integer array.

17. Is memory mapping named or anonymous?

       ​​​​​Memory mapping can be named or anonymous. File mapping (well-known), the mmap system call maps a portion of the contents of an ordinary file directly into the virtual address space of the calling process. Once mapped, the file contents can be accessed by manipulating bytes in the corresponding memory area. This mapping is also called file-based mapping.

       Anonymous mapping: Anonymous mapping has no corresponding file. This mapped memory area will be initialized to 0, and memory mapped by one process can share physical memory with mappings in other processes. Sharing means that the page table entries of each process point to the same page in RAM.

18. Talk about virtual memory

       From why there are two questions and disadvantages of virtual memory, the advantages and disadvantages of virtual memory, as follows; as follows; below;

19. How to check which dynamic libraries an executable program depends on?

       ​​ 1. Use the objdump command: View dependent libraries: objdump -x xxx.so | grep NEEDED View dependent libraries of executable programs: objdump -x ./path | grep NEDDED

       2. Use the readdlf command: check the dependent libraries: readelf -a xxx.so | grep "Shared", check the libraries the executable program depends on: readelf -a ./path | grep "Shared", check the dependent libraries: readelf - d xxx.so or readelf -d ./path. Check the .o files in the static library: readelf -d xxx.a

       ​​​ 3. Use the ldd command: Check the dependent libraries: ldd xxx.so, check the libraries the executable program depends on: ldd ./path

       ​ ​ 4. Check which processes are using a certain so on the server: lsof ***.so

20. How to kill multiple processes at the same time?

       Kill a single process based on a single process number: kill 2153, force kill the process with process number 2153: kill -9 2153,

Kill multiple processes (separate process numbers with spaces), kill xxx xxx xxx;

21. How is the virtual address converted to a physical address? What is the composition of the page table?

       The structure of the page table is as follows: 32 questions, the conversion of virtual address to physical address is completed through the memory management unit (MMU) of the operating system. The MMU is responsible for mapping virtual addresses to physical addresses. In a system that uses virtual memory, each process has its own virtual address space, which is divided into multiple pages (usually 4KB in size). Each page has a corresponding page table entry, which records the mapping relationship between virtual memory and physical pages. When a program asks for a virtual address, the MMU looks up the corresponding physical page based on the page table. If the virtual page is already in physical memory, the MMU converts the virtual address to a physical address and sends the access request to physical memory. If the virtual page is not in the physical memory, a page fault exception occurs, and the operating system loads the corresponding physical page into the memory and updates the page table. Summary: The conversion of virtual memory to physical address is achieved through the page table. The MMU maps the virtual address to the physical address according to the page table. This conversion mechanism allows each process to have its own virtual address space, thus achieving memory isolation and protection.

22. How are atomic operations implemented in the operating system?

       Processors implement atomic operations: Use methods based on cache locking or bus locking to implement atomic operations between multiple processors.

              1. Use bus locks to ensure atomicity: If multiple processors read, write, and modify shared variables at the same time, then the shared variables will be operated by multiple processors at the same time, so the read, modify, and write operations are not atomic. After the operation is completed, The value of the shared variable will be inconsistent with what is expected. If you want to ensure that the operation is atomic, you must ensure that when CPU1 reads or writes a shared variable, CPU2 cannot operate the cache that caches the memory address of the shared variable. It uses a LOCK# signal provided by the processor. When a processor outputs on the bus When this signal is issued, the requests of other processors will be blocked, and the requests of this processor can exclusively occupy the shared memory.

              ​​​​​​​ 2. Use cache locks to ensure atomicity. At the same time, we only need to ensure that the operation on a certain memory address is atomic, but the bus lock locks the communication between the CPU and the memory, which prevents other processors from operating data at other memory addresses during the lock period. , so the overhead of bus locking is relatively large. Currently, processors use cache locking instead of bus locking for optimization in some situations. Cache lock means that if the memory area is cached in the processor's cache line and is locked during the Lock operation, then when it performs the lock operation and writes back to the memory, the processor does not declare the LOCK# signal on the bus, but modifies it. memory address and allows its cache coherence mechanism to ensure atomicity of operations, because the cache coherence mechanism prevents simultaneous modification of data in memory areas cached by more than two processors when other processors write back cache lines that have been locked of data, invalidating the cache line. But there are two situations when the processor will not use cache locking: 1. When the data cannot be cached inside the processor, or the data being operated spans multiple cache lines, the processor will call bus locking. 2. Some processors do not support cache locking, and some processors will call bus locking even if the locked memory area is in the processor's cache line.

23. What are the methods of inter-process communication and what are their principles?

       Pipes are also known as pipes: Pipes are a half-duplex communication method. Data can only flow in one direction and can only be used between processes that are related. Inter-process affinity refers to the parent-child process relationship. Named pipes are also half-duplex communication methods, but they allow communication between unrelated processes.

       Signal: A semaphore is a counter that can be used to control the access of multiple processes to shared resources. It is often used as a lock mechanism to prevent other processes from accessing the resource when a process is accessing the shared resource. Therefore, it is mainly used as a process Synchronization means between time and between different threads within the same process.

       Message queue: The message queue is a link table of messages. It overcomes the shortcomings of limited semaphores in the 1.2 communication methods. A process with write permissions can add new messages to the message queue according to certain rules; it has read permissions on the message queue. The process can read information from the message queue. The basic idea is: based on the "producer-consumer" principle, the shared message buffer in the memory is used to realize information exchange between processes. Several message buffers are opened in the memory to store information. Whenever a process sends information to another process, it will apply for a message buffer, send the prepared message to the buffer, and then send the message The buffer is inserted into the message queue of the receiving process, and the process is finally notified to receive it. After the process receives the notification sent, it removes a message buffer from the message queue of this process, takes out the required information, and then removes the message buffer. Periodically sent to the system, which is responsible for managing shared messages and message delivery. A process can send messages to several processes. On the contrary, a process can receive messages from different processes. Obviously, the operation of the message queue in the process is a critical section. When the sending process is adding a message to the message queue of the receiving process, , the receiving process cannot export information from the message queue at the same time, and vice versa.

       Shared memory: It can be said to be the most useful inter-process communication method. It allows multiple processes to access the same memory space at the same time, and different processes can see updates to the data in the shared memory in each other's process in a timely manner. This approach requires some kind of synchronization operation, such as mutex locks and semaphores.

       Semaphores: Mainly used as a means of synchronization and mutual exclusion between processes and between different threads of the same process.

       Sockets: Sockets are also an inter-process communication mechanism. Unlike other mechanisms, they can be used for communication between different processes.

24. What are the communication methods between threads, and what are their principles?

       There are global variables, mutexes, semaphores, events, and critical sections.

       Implementation principle:

1. Global variables: Use global variables and add the volatile keyword to the variable so that the program reads the value from the memory every time instead of reading it from the cache due to compiler optimization.

2. Mutex: It is very similar to the critical area in function. After the thread owns the mutex, it enters the critical area state. Only one thread can own the mutex at a time.

3. Semaphore: It is the most historical synchronization mechanism and a key element in solving the producer-consumer problem. By using a spoof counter to represent the current number of available resources.

4. Events: Using events to synchronize threads is the most flexible. An event has two states: fired state and unfired state. Also called signaled state and no signal state. Events are divided into two types: manual reset events and automatic reset events. After the manual reset event is set to the fired state, it will wake up all waiting threads and remain in the fired state until the program resets it to the unfired state. After the automatic reset event is set to the fired state, "one" waiting thread will be awakened, and then automatically restored to the unfired state. So it is ideal to use automatic reset events to synchronize two threads.

5. Critical section

25. Is time slice considered resource allocation?

       Time slicing can be regarded as a method of resource allocation.

In computer operating systems, time slice means that the operating system divides the usage time of the processor into time segments of fixed length, and each time segment is assigned to a different task or process. At the end of each time slice, the operating system switches to the next task to ensure that each task has a chance to execute. This time slice allocation method is called round-robin scheduling.

The allocation of time slices is similar to resource allocation because processor usage time is a limited resource in a computer system. The operating system needs to reasonably allocate processor time to running tasks to ensure that each task can get sufficient processor time and to avoid a task occupying the processor for a long time and causing other tasks to not be executed.

The time slice round-robin scheduling algorithm aims to fairly allocate processor time. It can ensure that each task gets the same length of time slice, thereby preventing a task from occupying the processor for a long time. This fairness helps improve system responsiveness and user experience, especially in multitasking environments.

26. In multi-core, when multiple threads are started, if the time slice is a resource, is the time slice allocated to each process fixed? Why?

       On a multi-core processor, each core can perform tasks independently. When multiple threads or processes are started, in the time slice round robin scheduling algorithm, each process or thread will still be assigned a fixed length time slice to execute. Each core executes tasks in the order of time slices until the time slice is exhausted or the task is completed.

The length of the time slice is usually preset and is the same for all threads or processes. This is because using time slices of the same length ensures fairness and balance, and each thread or process has the same opportunity to obtain processor resources.

If each thread or process is assigned a time slice of different lengths, it may result in some threads or processes getting more processor time and other threads or processes getting less time. This can lead to an unfair system, where some tasks may not be completed in time, while other tasks have too many time slices to use, affecting overall performance and responsiveness.

By allocating a fixed-length time slice to each thread or process, the operating system can better control the order in which tasks are executed, ensuring that each task gets the appropriate amount of processor time and switches fairly between cores. This helps improve the load balancing and responsiveness of the system.

28.What are the protection mechanisms for processes in Linux, and what are they?

User-level process monitoring tool: The Linux system provides a variety of system calls to view process information, such as who, ps, top, etc. Through these system calls, we can clearly understand the running status and survival status of the process, and monitor and control the process. Protect.

29.What is the difference between process and thread?

Thread: It is the smallest unit that performs operations in the process. It is an entity in the process and the basic unit that is independently scheduled and assigned by the system. The thread does not own system resources, but only owns some resources that are indispensable during operation. Other threads in the process share all resources of the process and can execute concurrently.

Process: It is a process in which a program with independent functions is dynamically executed sequentially on a data collection.

the difference:

In terms of memory usage: processes take up a lot of memory, switching is complicated, CPU utilization is low, threads take up little memory, switching is simple, and CPU usage is high

In terms of destruction switching: process creation and destruction switching is complex, thread creation and destruction switching is simple and very fast.

In terms of programming and debugging: process programming and debugging is simple, thread programming is complex, and debugging is complex.

Reliability: Processes will not affect each other, and if one thread hangs up, the entire process will hang up.

Distributed: Processes are suitable for multi-core and multi-machine distribution, making it easy to expand machines, and threads are suitable for multi-core distribution.

30.What are the procedures for process switching?

Switch the new page table, then use the new virtual address, switch the kernel stack, add new content, and hardware context switch

31. Explain what coroutines are in C++?

It is a lightweight thread in user mode, and the scheduling of coroutines is completely controlled by the user. It has its own register context and stack. Directly operating the stack has basically no kernel switching overhead. Global variables can be accessed without locking, and context switching is very fast.

32.What is a page table?

       The page table is a data structure that stores the status of each virtual page, whether it is mapped, and whether it is cached. The process needs to know which data at the memory address is in the physical memory and which is not, and where on the physical memory the page needs to be used. table to record. Each entry in the page table is divided into two parts. The first part records whether the page is in physical memory, and the second part records the address of the physical memory page (if it is).

       Function: When the process accesses a virtual address and checks the page table, if it is found that the corresponding data is not in the physical memory, if the physical address memory is full and there is no free space, then find a page to cover it. Of course, if The overwritten page has been modified and needs to be written back to disk first.

       The status of the page table: If the effective address of the page table is 1, it means that the content stored in the virtual address is stored in the physical page.

If the effective position of the page table is 0, it means that the contents of the virtual storage are not stored in the physical page, a page missing exception occurs, and a page missing exception needs to be called to handle it.

       Working principle: 1. Our CPU wants to access the virtual page where the virtual address is located, and according to the page table, find the corresponding value in the page table. Determine the valid bit. If the valid bit is 1, the DRMA cache hits. According to the physical page number, find the content in the physical page and return.

       ​ ​ 2. If the valid bit is 0, the parameter page fault exception occurs, and the kernel page fault exception handler is called. The kernel will select a physical page as a sacrifice page, refresh the content of the page to the disk space, and then cache the disk file mapped by the page to the physical page, and then the valid bit of the corresponding value in the page becomes 1. The second part stores the contents that can correspond to the address of the physical memory page.

       3. After the page fault exception is processed, return to the instruction before the interruption and re-execute it. At this time, the cache hits and execute 1

       ​ ​ 4. Map the found content to the cache, the CPU obtains the value from the cache, and ends

33.Linux virtual memory mechanism:

       Linux divides virtual memory into a collection of regions. A region includes multiple consecutive pages. The data structure diagram of the region is as follows:

       The kernel maintains a separate task result task_struct for each process

       The struct mm_struct* mm pointer in Task_struct points to mm_struct, which describes the running status of virtual memory.

       The pgd pointer in the Mm_struct structure points to the base address of the first-level page of the process, and the mmap pointer points to the vm_area_struct linked list.

       Vm_area_struct describes the structure of the area. vm_start indicates the start position of the area, vm_end indicates the end position of the area, vm_port indicates the read and write permissions in the area, vm_flags indicates whether the page table in the area is private or shared by the process, and vm_next points to the next area. node.

34. Advantages of virtual memory mechanism:

1. Since the memory space of each process is consistent and fixed (4G on 32-bit platforms), the linker can set the memory address when linking the executable file without having to worry about the final actual memory of these data. address, which is left to the kernel to complete the mapping relationship.

2. When different processes use the same piece of code, such as the code of a library file, only one copy of such code can be stored in physical memory. Different processes only need to map their own virtual memory to it, which can save physical memory. .

3. When the program needs to allocate continuous space, it only needs to allocate continuous space in virtual memory, and does not need continuous physical memory. In fact, physical memory is often intermittent memory fragments. This makes efficient use of our physical memory.

Guess you like

Origin blog.csdn.net/songbijian/article/details/132570427