iOS concept of tackling the road (four): Multithreading

Foreword

Mode operating system we use today are multitasking (Multi-tasking) system , the operating system takes over all of the hardware resources, but is itself running on a hardware level protection. All applications are based on processes (Progress) mode of operation at a lower level than the operating system permissions. Each process has its own separate address space, so that the address space between processes isolated from each other. CPU unified by the operating system assigns each process gets CPU process according to the level of priority have the opportunity, however, if the running time exceeds a certain event, the operating system will suspend the process to allocate CPU resources to other waiting to run process. This CPU allocation of so-called preemptive (Preemptive) , the operating system can be forced deprived of CPU resources allocated to it and thought process needs most, the time allocated to each operating system if the process is very short, that is, the CPU fast switching between multiple processes, resulting in the illusion of many processes running at the same time. Almost all modern operating systems are based on this approach.

Development of early computers, a CPU can run only one program, when performing I / O operations, such as read data disk, CPU will be idle, which is obviously a waste. Later, people invented a rapid multi-channel program (multiprogramming) , when a program without using the CPU, monitor put additional CPU resource is waiting to start a program, but it does not have a concept of priority, even if certain tasks in urgent need of CPU it is also likely to have to wait a very long time. After improvements, people invented a time-sharing system (Time-Share System) , each program running for some time have taken the initiative to yield the CPU to other programs, so that each program over a period of time have the opportunity to run for a short time. But the problem with this system is that if a program during a very time-consuming operation, has been occupied CPU, then the operating system is no way such a program has entered a while(1)cycle of death, then the whole system will stop. Further development is multi-tasking system we mentioned above the.

The purpose of such a development is, as far as possible to maximize the use of CPU, here, there was the concept of a process, and threads and processes, has tied up the relationship.

What is the process

Wikipedia:

Process (Process) , the computer is already running the program entities. Once the process is the basic operational unit of time-sharing system. In the system for process design (such as early UNIX, Linux2.4 and earlier), the basic process is the implementation of the program of the entity; thread-oriented design of the system (such as most modern operating systems, Linux 2.6 and later) , the process itself is not the basic operation of the unit, but the container threads . Program itself is only instructions, data organization and description of the process is the program (those instructions and data) to achieve a real run.

After the user orders to run the program, it will have a process. The same program can generate multiple processes (many relationship) to allow simultaneous multiple users running the same program, but it will not conflict with each other.

Process requires some resources to complete the work, such as CPU time, memory, and file I / O devices, and is sequentially one by one, that is only running one process per CPU core within any time.

Baidu Encyclopedia:

Process (Process) is a computer program run on a set of data on the activities of , it is the system of resource allocation basic unit and scheduling, is the underlying operating system architecture. In the computer architecture for the early design process, the basic process is the execution of the program entity; in contemporary computer architecture design for the thread, the process is the thread of the container . Program is instruction, organization of data and its description of the process is a solid program.

Process is a program run event having individual functions on a data set. It can apply to have the systems and resources, is a dynamic concept, it is an active entity. It is not only the program code further comprising a current activity represented by a processing register contents and the value of the program counter.

There are two main concepts of the process: first, the process is an entity. Each process has its own address space, under normal circumstances, including the text area (text region), the data region (data region) and stack (stack region). Code is executed by a processor stored text area; dynamically allocated memory area stores data used during execution process variables; stack area stores instructions and local variables of the calling process activities. Second, the process is a "executing programs." Program is a lifeless entity (operating system performs the) only when the processor attached to the program of life, it can become an active entity, we call for the process.

Therefore, the process is an entity program, the program is executed, and the program is the instruction, and the data organization described. Can not perform alone, only to load the program into memory before the system can allocate resources for its execution, this program execution is called process. So the process is a dynamic concept, with the difference that program, the program is a set of instructions, static text describing processes running, and the process is a dynamic activity programs executed on the system.

It can be understood, we write the APP, is a program we installed to the phone, this time it is not the process, when we click on it, the system allocates resources for it to run, then it can be called a process.

The other two are mentioned in the structure of modern computer program for the design, the process is the thread of the container. In today's operating systems, the thread is the smallest unit of scheduling, and the process is the smallest unit of resource allocation, a process that contains one or more threads.

Look at the contents of the process:

  • A machine code executable image of the program in that memory.
  • Allocating memory to another (usually a virtual memory area a). Contents of the memory including executable code, process-specific data (input, output), a call stack, the stack (for save data generated during the transportation operation).
  • Resources allocated to the process and the operating system descriptors, such as a file descriptor (UNIX terminology) or a file handle (the Windows), data sources and data terminal.
  • Security features, such as process owners and process privilege set (permissible operation).
  • Processor Status (Chinese), such as register contents, physical memory addressing and the like. When the process is running, the state is typically stored in a register, otherwise the memory.

What is the thread

Kernel threads, lightweight processes, users thread

As mentioned earlier, the process is the thread of the container, and in most modern operating systems, a thread is the smallest unit of scheduling. Let's look at the definition of threads:

Wikipedia:

The thread (Thread) is the minimum unit of the operating system can schedule calculation. It is included in the process, it is in the process of the actual operation of the unit . A thread refers to a process sequence of a single control flow , concurrently process a plurality of threads, each thread in parallel to perform different tasks. In the SunOS Unix System V and is also referred to as lightweight processes (lightweight processes), but more lightweight process refers to kernel threads (kernel thread), while the user thread (user thread) called threads.

Here he mentions several concepts: kernel threads, lightweight processes, user threads, we were to look at their specific concepts:

Kernel threads

Kernel thread is the kernel of the avatar, avatar can handle a specific task. This is particularly useful when dealing with asynchronous events such as asynchronous IO. Kernel threads is cheap, the only use of resources is to save space when the kernel stack and register context switching. Supports multi-threaded kernel is called the multi-threaded kernel (Multi-Threads kernel).

Kernel threads run only in kernel mode, user mode without the context of a drag.

LWP

Lightweight process (LWP) is a kind of kernel threads supported users . It is based on highly abstract kernel threads, so only the first support kernel threads, in order to have LWP. Each process has one or more LWP, each LWP consists of a kernel thread support. This model is known as one model. In this implementation of the operating system, LWP is a user thread.

Since each LWP is associated with a particular kernel thread, each thread is an independent LWP scheduling unit. Even with a LWP blocking in a system call, it will not affect the implementation of the entire process.

LWP limitations:

  • Most LWP operations, such as creating, destructors and synchronization, system calls are required, the relatively high cost of the system call (need to switch user mode and kernel mode)
  • Each LWP need to have a kernel thread support, so LWP consumes kernel resources (kernel thread stack space). Therefore, a system can not support a large number of LWP. (P picture refers to the process)

The reason it is called a lightweight process might be: with the support of kernel threads, LWP is independent of scheduling unit, the same as a normal process. So the most important feature is each LWP LWP has a kernel thread support.

Users thread

LWP Although they are essentially user threads, but LWP thread library is built on top of the kernel, many operating system calls LWP should be carried out, and therefore inefficient. And here's the user thread refers entirely on user space threads library , create a user thread, synchronization, destroyed completely in user space scheduling is complete, without the aid of the kernel, so this operation is its quick and thread low consumption.

The figure is the first model of a user thread, can be seen, the process includes threads, user threads implemented in user space, the kernel has no direct user thread scheduling, dispatching kernel objects and traditional processes, like, or the process itself the kernel does not know the existence of the user threads. Scheduling between user threads achieved by the thread library in user control.

This is a many-to-model, the drawback is that if a user thread is blocked in a system call, the entire process will be blocked.

Enhanced version of the user thread - user thread + LWP

This model is called a many-to-model. User thread library or build entirely in user space, the operator of the user thread is still very cheap, so you can build as many needs of users thread. The operating system provides LWP as a bridge between user threads and kernel threads. LWP and still mentioned earlier, has a kernel thread support, kernel scheduling unit, and the user's system calls to thread through LWP, and therefore the process of blocking a user thread does not affect the implementation of the entire process. Users threads library will establish a user associated with the thread on the LWP, LWP and the number of user threads do not necessarily match. When the kernel scheduler to a LWP, the case is executed with the LWP associated with the user thread.

Many believe that literature is a lightweight process thread, in fact, this statement is not entirely correct, only if the user thread is composed entirely of lightweight processes, we can say that the process is lightweight threads.

For more information about kernel threads, lightweight processes, the concept of three kinds of threads the user thread, you can take a look at this article .

In modern operating systems, the process will no longer operate as a basic unit, but the thread as a basic unit, a process can contain multiple threads. All threads within a process share the virtual memory space. This concept is still in a process of one or more threads of containers preserved form. Multi-threaded processes are often, but when a single-threaded process, processes and threads belong to two can be used interchangeably.

Thread structure, access rights

A standard thread by the thread ID, the current instruction pointer (PC), register set and stack components. A general sense, to a process of a plurality of threads, the program memory space shared between threads (including code segments, data segments, stack, etc.) and a number of process-level resources (such as open files and signals), the following is a block diagram of the relationship between threads and processes:

Threads can access all data in the memory process, even including other thread's stack (if it knows the address of the stack of other threads, but this is rare), in practice, the thread also has its own private memory space, including the following aspects:

  • Stack (although not completely unable to be accessed by other threads, but generally still be considered private resources)
  • TLS (Thread Local Storage, thread-local storage). TLS is a certain operating system threads to provide a separate private space, usually only have a very limited capacity
  • Register (including the PC register), the register is performed elementary stream, and therefore the thread private

Whether private data threads and processes in the following table:

Thread-private Share (all processes) between processes
Local variables Global Variables
Function parameters Heap of data
TLS Static variables in functions
Program code, any thread has the right to read and execute any code
Open files, A thread can read and write file opened by the thread B

Thread scheduling and priorities

Whether multi-processor or single processor, we always seem to see the thread of execution "concurrency", the reality is that only when the number of threads is less than or equal to the number of processors (multi-processor support and operating system), concurrent threads of real concurrency (that is, parallel), running in different threads on different processors, unrelated to each other. For the case where the number of threads is greater than the number of processors, at least one processor may run multiple threads, only a case of concurrent simulated state: the operating system will turn the multi-threaded program execution, each execution only in small pieces time (usually several tens to hundreds of milliseconds), so that each thread "looks" at the same time performing.

Such a constant switching behavior of different threads on a processor called thread scheduling (the Thread the Schedule) , thread scheduling, thread typically has at least three states, namely:

  • Running (Running) : At this time executing thread
  • Ready (Ready) : At this time, the thread can be executed at once, but the CPU has been occupied
  • Waiting (Waiting) : At this point the thread is waiting for an event (usually I / O or synchronization) occurs, can not be executed

Look at the threads of the life cycle:

In operation for some time may have a thread of execution, this time called a time slice (Time Slice) , when the time slice is exhausted, the thread into the ready state. If a thread before time began to run out of film waiting for an event, then it goes into a wait state. Whenever a thread left running, scheduling system will choose one of the other threads ready to continue. After a thread in a wait state waiting for an event occurs, the thread into the ready state.

Thread scheduling since the advent of multi-tasking operating system will continue to be put forward different programs and algorithms. While the mainstream of scheduling different, but all with priority scheduling (Priority Schedule) and the rotation method (Round Robin) trace. The so-called round-robin, which in turn is to let each thread execute a short time before-mentioned method, which determines the staggered between the threads are running. The priority scheduling is decided in what order threads execute in turn. In a system with priority scheduling, the thread has its own thread priority (the Thread Priority) . Thread with a higher priority will be executed earlier, while low priority thread often have to wait until the system has no higher priority thread there is an executable can be executed.

The system will automatically adjust the performance of different threads according to priority, so that scheduling more efficient. For example, under normal circumstances, frequently enter the wait state (waiting to enter the state, will give up after a time share class is still occupied, that is, we say the thread to sleep, do not take up CPU resources) threads (eg handle I / O threads) computing a lot more than frequently, so that every time the time slice is used up more threads to be popular. Generally the waiting thread frequently called IO intensive threads (IO Bound the Thread) , while waiting for the little thread called CPU-intensive thread (CPU Bound the Thread) . IO-intensive than CPU-intensive thread thread is always easy to get priority upgrade.

In priority scheduling, there is a starvation (Starvation) phenomenon, a thread is starved to death, it is a lower priority, before it performs, there is always a high priority thread to be executed, so this low priority thread never been able to perform. When a CPU-intensive get a higher priority thread, many low-priority thread is likely to starve to death. And a high-priority thread IO-intensive because most of the time in a wait state, and therefore relatively likely to cause other threads to starve to death. To avoid starvation phenomenon, often gradually improve scheduling system that waited too long thread of execution can not be a priority. In such means, a thread just waiting for enough events, priority will be increased to the extent sufficient to make it perform.

In summary, under priority scheduling environment, change the thread priority generally three ways:

  • Users specify the priority
  • Raise or lower the priority according to how frequently enter the wait state
  • Prolonged lack of execution is lifted priority

Thread Safety

Multithreaded program in a changing environment, global variables and stack data can be accessed at any time may be changed in the other thread, multi-threaded program consistency of the data becomes very important when concurrency.

In order to avoid multiple threads simultaneously read and write the same data and have unpredictable consequences, we want each thread to access the same data synchronization (Synchronization) . The so-called synchronous, meaning that when one thread to access the data is not completed, other threads can not access the same data. Thus, access to the data is atomized.

Atomic operations: the operation of a single instruction, however, a single instruction will not be interrupted.

The most common method is to use a synchronous lock (Lock) . A lock is a non-mandatory mechanisms, each thread first before trying to access data or resource acquisition (Acquire) lock, and after the end of the visit released (Release) lock. At the time lock has been occupied by trying to acquire the lock, the thread will wait until the lock is available again.

Binary flag that amount (Binary Semaphore) is the easiest lock, it has only two states: occupied and unoccupied. It is suitable for exclusive access to resources can only be a single thread. When the binary flag in the amount of unoccupied state, the first attempt to obtain this binary semaphore thread will acquire the lock and binary flag that amount is set to an occupied state, then all the other trying to get this binary semaphore the thread will wait until the lock is released.

For resource allows concurrent access by multiple threads, semaphores referred to as multi- Semaphore (Semaphore) , it is a good choice. An initial value N N semaphore allows concurrent threads to access. Thread when accessing resources first acquire a semaphore, proceed as follows:

  1. Save the value of the semaphore 1
  2. If the semaphore's value is less than 0, the process proceeds to a wait state, otherwise continue

After completion of resource access, thread releases the semaphore, proceed as follows:

  1. The semaphore value plus 1
  2. If a wait semaphore value is less than 1, wake up threads

Mutex (Mutex) and binary semaphores very similar resources while allowing only one thread to access, but the difference is that semaphores and semaphore can be acquired and released any thread throughout the system, that is, the same signal after obtaining the amount that can be released by another thread a thread in the system. The mutex which thread is required to acquire the mutex, which thread will be responsible for releasing the lock, other threads to release the mutex is invalid.

Critical region (Cirtical Section) is more stringent than the mutex synchronization means. In the term, the lock acquisition is called the critical region enter the critical section, and to release the lock to leave the critical section is referred to. The critical difference between the area and the mutex and a semaphore that mutex and a semaphore in any process in the system are visible, that is to say, a process creates a mutex or semaphore, another process tries to acquire the lock is legal. However, the scope is limited to this critical area of the process, other processes can not obtain the lock. In addition. Critical region and having the same properties as the mutex.

Read-Write Lock (Read-Write Lock) is committed to a more specific occasions synchronization. For a piece of data, multiple threads simultaneously read is always no problem, but assuming the operation is not atomic type, as long as there is a thread of any attempt to modify this data, you must use the synchronization means to avoid errors. If we use any of the above semaphore, mutex or critical section to synchronize, although it is possible to ensure that the correct procedures, but in the case of frequently read, but only occasionally written, it will become very inefficient. Read-write locks can avoid this problem. For the same lock, there are two read-write lock acquisition mode, shared (the Shared) and exclusive (Exclusive) . When the lock is in a free state, attempt to acquire a lock in any way to be successful, locks and put the corresponding state. If the lock is shared, other threads to share ways to acquire the lock will still succeed, then the lock is assigned to multiple threads. However, if another thread tries to acquire an exclusive lock is already way in the shared state, it will have to wait for a lock to be released all threads. Accordingly, the lock is in an exclusive state will prevent any other thread to acquire the lock, regardless of the manner in which they are trying to obtain. Read-write lock behavior can be summarized in the following table:

Read-Write Lock status Get in a shared manner Gets Exclusive
free success success
shared success wait
Monopoly wait wait

Condition variable (Condition Variable) as a synchronization means, it acts like a barrier. For condition variables, there are two operating threads, the first thread can wait condition variable, waiting for a condition variable may be a plurality of threads. Secondly, the thread can wake up condition variable, then one or all threads waiting on this condition variable wakes up and will continue to support. That is, using condition variables allows many threads to wait for an event to occur together, when an event occurs (condition variable is awakened), all the threads together can resume execution.

Lock and thread synchronization, will then open a separate article, the lock of the concept is the same, but the means to achieve not the same.

The origin of threads and processes

I was watching a simple explanation of processes and threads of this article, see an answer, to explain the origin of processes and threads is appropriate:

  1. In the single-core computer, there is a resource that can not be used in parallel multiple applications: CPU.

Without an operating system, the program has been a monopoly with all of the CPU.

If you have two tasks to share a CPU, the programmer needs to be carefully arranged for the program to run programs - some exclusive to CPU time by the program A, the next time the program by the CPU to exclusive B.

And this plan of arrangement later became the core component of the OS, are individually named Scheduler (Scheduler) . It is concerned with how to run only a single CPU is split into a section of the "running status", turn to different sub-program to use, and in the high level, since the fast switching speed distribution, it is manufactured in a parallel multithreaded illusion on a CPU.

  1. In the single-core computer, there is a shared resource may be a plurality of programs, however, will lead trouble: memory.

Only in a scheduler, no memory management component operating system programmers need space to run manually schedule for each program - the program address A use of force 0x00-0xff, procedure B using the physical address 0x100-0x1ff, and the like.

Doing so, however there is a big problem: Each program should be coordinated with a good discussion on how to use a different memory space, software systems and hardware systems vary widely, so that custom solutions not feasible.

To solve this trouble, computer introduces the concept of "virtual memory", and start from three aspects to do:

  • Hardware, CPU adds a special module called MMU, responsible for translating virtual addresses and physical addresses
  • The operating system, the operating system adds another core components: "Memory Management", that is, memory management module that manages the physical memory, virtual memory-related series of transactions.
  • On the application, the invention of a model called the "process" of each process with exactly the same virtual address space, and then through the operating system and hardware MMU collaboration mapped to different physical address space. Different "process" has its own separate physical memory space, do not have some special means, is unable to access the physical memory of another process.
  1. Now, the different applications, you can not care about the underlying physical memory allocation, or care coordination sharing the CPU. But there is one problem: there are some programs, you want to share CPU, and also share the same physical memory, this time, a "thread" model called appeared, they were wrapped inside the process, the scheduler under the management of shared CPU, have the same virtual address space, but also share the same physical address space, however, they can not get past wrap themselves in the process to access the physical address space of another process.

Why use multithreading

  • An action may fall into a long wait and wait for the thread to sleep, unable to continue. Multithreaded execution waiting time can be effectively used, a typical example is to wait for a network response.
  • An action (often calculated) will consume a lot of time, if the interaction will be between only one thread, and user interrupts. Multithreading allows a thread is responsible for interaction, another thread is responsible for the calculation.
  • Program logic itself requires complicated operations such as a multi-terminal downloading software.
  • Multi-CPU or multi-core computer, itself has the ability to execute multiple threads simultaneously, so a single-threaded program can not complete their full computing power.
  • Relative to the reference multi-process, multi-threaded data sharing in terms of efficiency is much higher.

to sum up

In fact, we are the two most important questions: What is the process and what is the thread.

What is the process?

Process is the main computer has been running the program in the previous time-sharing system, is the basic unit of operation of the system. But for today's multithreaded design of the system, the process is the thread of the container. Its two main concepts: first, the process is an entity, each process has its own address space. Second, the process is the execution of a program, the program is a living entity is not only the processor attached to the program of life (such as click to run), it can become an active entity, which is the process.

The process is the smallest unit of the system for resource allocation.

What is a thread?

Thread, sometimes called lightweight processes, it is included in the process, the actual operation of the unit process, a thread refers to the process of the execution flow of a single sequence. All threads share data processes and have their own private storage space. Thread is divided into kernel threads and user threads.

The thread is the smallest unit of scheduling system.

When we want to run a program, the system allocates resources for us, and then run, this time called the process, but the process is not really running, but the flow of execution within a process, which is a thread, a process has at least one thread.

In addition there are a number of thread-related knowledge, such as thread access, structure, life cycle, security and so on.

The topic of the thread and prolonged process, if there is to understand the text in the wrong place, welcome to point out.

Reference article

iOS full range of multi-threading

Kernel threads, lightweight processes, user threads three kinds of thread concept doubts (≠ threads lightweight processes)

A simple explanation of processes and threads

Guess you like

Origin blog.csdn.net/weixin_34368949/article/details/91380695