编程知识 cdmana.com

Operating system concept learning notes 9 threads

Operating system concept learning notes 9

Threads


summary

A single process can include multiple control threads .

Threads —— A kind of CPU Use the basic unit of , It's the foundation of a multithreaded computer .

Thread is CPU The basic unit used , It's made up of threads ID、 Program counter 、 Register set and stack composition . It shares code snippets with other threads that belong to the unified process 、 Data segments and other operating system resources .

A traditional heavyweight process has only a single control thread , If the process has multiple control threads , So you can do multiple tasks at the same time .

Single thread and multi thread

motivation

An application is usually implemented as an independent process with multiple control threads . If a busy web server has more than one ( Or thousands ) Clients access it concurrently , You can create multiple threads instead of processes , Because the creation process takes a lot of time , A single thread process can only process one request at a time .

Thread in remote procedure call (RPC) The system also plays an important role , Usually ,PRC The server is multithreaded . When a server receives a message , It uses independent threads to process messages , This allows the server to handle multiple concurrent requests .

Many modern operating systems are multithreaded , A few threads are running in the kernel , Each thread completes a specified task .

Advantages of multithreading

  1. High responsiveness : Even if it partially blocks or performs lengthy operations , The program can still be executed , Thus, the corresponding degree to users is increased .
  2. Resource sharing : By default, threads share the memory and resources of the process to which they belong . The advantage of code and data sharing is that it allows an application to have multiple active threads in the same address space .
  3. economic : The allocation of memory and resources required for process creation is expensive . Because threads can share the resources of the process to which they belong , So it's more economical to create and switch threads .
  4. Utilization of multiprocessor architecture : One of the advantages of multithreading is that it can make full use of multiprocessor architecture . So that each process can run in parallel on different processors . No matter how many CPU, Single threaded processes can only run on one CPU On , In a multiple CPU Multithreading is used to enhance the concurrency function .

Multithreading model :

There are two different ways to provide threading support : User layer User threads And kernel layer Kernel thread . User threads are supported by the kernel , Without kernel management ; The kernel thread is supported and managed by the operating system . In fact, all modern operating systems support kernel threads . There must be a relationship between user thread and kernel thread .

The first mock exam model :

Many to the first mock exam maps many user level threads to a kernel thread. . Thread management is carried out by thread library in user space , Therefore, the efficiency is relatively high . But if a thread performs a blocking system call , Then the whole thread will block . Because only one thread can access the kernel at any time , Multiple threads cannot run in parallel on multiprocessors .

One to one model the first mock exam :

One to the first mock exam, each user thread is mapped to a kernel thread. . When a thread executes a blocking system call , Allows another thread to continue execution . It also allows multiple threads to run in parallel on multiprocessor systems , The only drawback of this model is that every user thread created will create a corresponding kernel thread . The overhead of creating kernel threads can affect the performance of the application , So most implementations of this model limit the number of threads supported by the operating system .

Many to many model :

The many to many model multiplexes many user threads to the same or smaller number of kernel threads . The many to many model does not have the disadvantages of both : Developers can create as many user threads as you want , And the corresponding kernel threads can be executed concurrently on multiprocessor systems . And when a thread executes a blocking system call , The kernel can schedule another thread to execute .

A variation of the popular many to many model still multiplexes many user threads to the same or smaller number of kernel threads , But it also allows a user thread to be bound to a kernel thread . This variant is known as a secondary model .

thread library): For programmers to create and manage threads API. There are two main ways to implement thread library .

(1) Provide a library in user space without kernel support , All code and data structures for this library exist in user space . Knowledge of a function in the call library causes a local function call in user space , It's not a system call .

(2) Execute a kernel level library directly supported by the operating system . here , The code and data structure of the library exist in kernel space . Call one of the libraries API Functions usually result in system calls to the kernel .

The three main thread libraries currently in use are :

(1)POSIX Pthread (2)Win32 (3)Java

Pthread As POSIX Standard extension , User level or kernel level libraries can be provided .Win32 Thread library is suitable for Windows Kernel level thread library of operating system .Java Threads API Allow threads to be in java Create and manage directly in the program . However , Because most JVM The instance runs on the host operating system ,Java Threads API It is usually implemented by the thread library on the host system .

Pthread

Pthread By POSIX Standard is defined for thread creation and synchronization API. This is the specification of thread behavior , Not implementation . Operating system designers can implement it in any form they wish .

all Pthread All procedures need to be included pthread.h The header file .

Pthread_t tid The identifier of a common thread is declared . Each thread has a set of properties , Including stack size and scheduling information .

Pthread_attr_t attr Represents the properties of a thread , Call through function pthread_attr_init(&attr) To set these properties .

Pthread_create() Create a separate thread . In addition to passing the thread identifier and thread properties , Also pass the function name .

pthread_join() Function to wait for

pthread_exit() complete

Pthread Example program :

The following example of experimental procedures to achieve concurrent two threads will be integer X From 1 Add to 10 The work of can . They send calculation results to each other through pipes .

/*
* description
:  tpipe.c
* copyright
: (C)2015  by  Sun Mingchao 
* Function
:  Using pipeline to transfer integer between programs 
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void task1(int *); // Threads  1  Execution function prototype 
void task2(int *); // Threads  2  Execution function prototype 
int pipe1[2],pipe2[2];// Store two nameless pipe labels 
pthread_t thrd1,thrd2;// Store two thread IDs 
int main(int argc,char *arg[])
{
int ret;
int num1,num2;
// Use pipe() The system call creates two anonymous pipes . Failed to create program exit , Termination of execution 
if(pipe(pipe1) < 0){
perror("pipe not create");
exit(EXIT_FAILURE);
}
if(pipe(pipe2) < 0){
perror("pipe not create");
exit(EXIT_FAILURE);
}
// Use pthread_create The system call establishes two threads . Failed to create program exit , Termination of execution 
num1 = 1 ;
ret = pthread_create(&thrd1,NULL,(void *) task1,(void *) &num1);
if(ret){
perror("pthread_create: task1");
exit(EXIT_FAILURE);
}
num2 = 2 ;
ret = pthread_create(&thrd2,NULL,(void *) task2,(void *) &num2);
if(ret){
perror("pthread_create: task2");
exit(EXIT_FAILURE);
}
// Suspend current thread switch to thrd2  Threads 
pthread_join(thrd2,NULL);
// Suspend current thread switch to thrd1  Threads 
pthread_join(thrd1,NULL);
exit(EXIT_SUCCESS);
}
// Threads  1  Execute function , It first writes to the pipe , And then read it from the pipe 
void task1(int *num)
{
int x=1;
// Each cycle to the pipe  1  Of  1  End write variable X Value , And from 
// The Conduit  2  Of  0  End read an integer write X Right again X Add  1, until X Greater than  10
do{
printf("thread%d read: %d\n",*num,x++);
write(pipe1[1],&x,sizeof(int));
read(pipe2[0],&x,sizeof(int));
}while(x<=9);
// After reading and writing , Close the pipe 
close(pipe1[1]);
close(pipe2[0]);
}
// Threads  1  Execute function , It first reads from the pipe , Then write to the pipe 
void task2(int * num)
{
int x;
// Each cycle from the pipe  1  Of  0  Read an integer into a variable X in ,
// Also on X Add  1  Post write pipe  2  Of  1  End , until X Greater than  10
do{
read(pipe1[0],&x,sizeof(int));
printf("thread2 read: %d\n",x++);
write(pipe2[1],&x,sizeof(int));
}while( x<=9 );
// After reading and writing , Close the pipe 
close(pipe1[0]);
close(pipe2[1]);
}

Running results :

sora@sora:~/SORA/program/Pthread$ gcc -g -c demo.c
sora@sora:~/SORA/program/Pthread$ gcc demo.o -l pthread -o demo
sora@sora:~/SORA/program/Pthread$ ./demo 
thread1 read: 1
thread2 read: 2
thread1 read: 3
thread2 read: 4
thread1 read: 5
thread2 read: 6
thread1 read: 7
thread2 read: 8
thread1 read: 9
thread2 read: 10

Win32 Threads

Win32 The technology of creating threads in thread library is similar to that of thread library in some aspects Pthread technology .

Win32 Threads :Win32 API Must include windows.h The header file

The thread is created using the CreateThread() Pass a set of thread properties to this function .

stay Pthread The pthread_join() Statement to achieve thread waiting , stay Win32 The function with the same function is used in WaitForSingleObject(), This causes the creator thread to block .

Java Threads

Java Threads : Thread is Java The basic model of program execution in program .

all Java There is at least one thread control program , Even if only one main() The simplicity of function Java The program is also in JVM Running as a thread in .

Java There are two techniques for creating threads in programs .

(1) Create a new class , It is from Thread Class derivation , And overload its run() function .

(2) Define an implementation Runnable() The class of the interface . When a class executes runnable() when , He has to define it run() function , To achieve run() The code for the function is executed as a separate thread .

establish Thread Sex does not create a new thread , Actually start() Function to create a new thread . Call for a new object start() Functions need to do two things :

One is in JVM Allocate memory and initialize new threads ;

Two is the call. run() function , Implementation thread is suitable for JVM Run in ( Be careful , Never direct run() function , But the call start() function , It then calls run() function ).

And pthread_join() Corresponding java There is join() function .

Three more :

stay Win32 and Pthread It's easy to share data , Shared data can be simply declared as global data . And for Java There is no concept of global data , stay Java If two or more threads need to share data , This is achieved by passing a reference to the shared object to the corresponding thread .

Multithreading problem

system call fork() and exec()

In multithreaded programs , system call fork() and exec() The meaning of "has changed" .

If a process in the program calls fork(), Then the new process copies all threads , Or does the new process have a single thread ? yes , we have UNIX The system has two forms fork(), A copy of all threads , The other only copies and calls the system call fork() The thread of .

Exec() Operation mode : If a thread calls the system call exec(), that exec() The procedure specified by the parameter replaces the entire process , Include all threads .

If the fork() Call immediately after exec(), Then there is no need to copy all threads , because exec() The procedure specified by the parameter replaces the entire process . under these circumstances , It is appropriate to copy only the calling thread . however , If in fork() After that, another process does not call exec(), Then the other process should replicate all processes .

Cancel

Thread cancellation (thread cancellation) A task that terminates a thread before it completes .

The thread to cancel is usually called Target thread . Cancellation of the target thread can occur in two cases :

One is Asynchronous cancellation (asynchronous cancellation): A thread immediately terminates the target thread .

Two is Delay cancellation (deferred cancellation): The target thread constantly checks whether it should terminate , This allows the target thread the opportunity to terminate itself in an orderly manner .

If the resource is already assigned to the thread to cancel , Or the thread you want to cancel is updating data shared with other threads , Then it will be difficult to cancel , It is particularly troublesome for asynchronous cancellations . Operating system reclaims system resources for cancellation threads , But not all resources are usually recovered . therefore , Canceling a thread asynchronously does not idle the required system resources . On the contrary, delayed cancellation is adopted , Allows a thread to check if it is cancelled at a safe point ,pthread These points are called cancellation points (cancellation point)

signal processing

signal processing : The signal is Unix Is used to notify the process that a specific time has occurred , Signals can be received synchronously or asynchronously . All signals have the same pattern :

(1) Signals are generated by the occurrence of a specific event

(2) The generated signal is sent to the process

(3) Once sent , Signals must be transacted .

Examples of synchronous signals include accessing illegal memory or being 0 except . under these circumstances , If the running program performs these actions , Then a signal is generated , The synchronization signal is sent to the same process that performs the operation and generates the signal ( Reasons for synchronization ).

When a signal is generated by an event outside the running process , The process receives the signal asynchronously . Examples of such signals include the use of special keys (Ctrl + C) Or timer expired . Usually , An asynchronous signal is sent to another process .

Each signal may be processed by one of two possible processing programs :

(1) Default signal processor

(2) User defined signal processing program

Each signal has a default signal handler , When the processing signal is running in the kernel , This default action can be rewritten with a user-defined signal handler . Signals can be processed in different ways . Some signals can be simply ignored ( Such as changing the window size ), Some need to terminate the program to handle ( Illegal memory access )

The signal processing of single thread program is more direct , Signals are always sent to the process .

When multithreading , Signal meeting

(1) Send the signal to the thread to which the signal is applied

(2) Send a signal to each thread in the process

(3) Send signals to certain fixed threads within the process

(4) Specifies a specific thread to receive all signals from the process .

The method of sending a signal depends on the type of signal .

Most threaded versions Unix Allow the thread to describe what signals it will receive and what signals it will reject ., Because the signal can only be processed once , So the signal is usually sent to the first thread that doesn't reject it .

pthread It also provides pthread_kill function , This function allows the limit to be passed to a specified thread .

Windows, Through asynchronous procedure calls (asynchronous procedure call,APC) To simulate the signal .

Thread pool

There are some potential problems with multithreaded servers : The first is about the time used to create the thread before processing the request , And the fact that threads are discarded after they finish their work . the second , If you allow all concurrent requests to be processed through the new thread , Then there is no way to limit the number of concurrent threads in the system . Unlimited threads can run out of system resources . The solution to this problem is to use thread pools .

The idea of thread pool is to create a certain number of threads at the beginning of a process , And put it into the pool to wait for work . When the server receives the request , He wakes a thread in the pool , And pass on the request to be processed to him , Once the thread completes the service , It will return to the pool and wait for work . If there are no available threads in the pool , Then the server will wait until there is an empty thread .

Advantages of thread pool :

(1) It's usually faster to process requests with an existing thread than to wait for a new thread to be created

(2) Thread pools limit the number of threads available at any time .

The number of threads in the thread pool is determined by the system CPU The number of 、 The size of physical memory and the expected value of concurrent client requests determine . More advanced thread pool can dynamically adjust the number of threads , In order to adapt to the specific situation .

Thread specific data

Threads belonging to the same process share process data .

In some cases, each thread may need its own copy of certain data , This data is called Thread specific data . You can associate each thread with its unique identifier .

Scheduler activation

Communication between kernel and thread library , It's about the many to many model . This coordination allows you to dynamically adjust the number of kernel threads to ensure its best performance .

Set up an intermediate data structure between user kernel threads . Lightweight process (LWP), It is represented as a virtual processor in which applications can schedule user threads to run . Every LWP Connect to kernel thread , The kernel thread is scheduled by the operating system to run on the physical processor , If the kernel thread is blocked ,LWP Blocking , And LWP Connected user threads are also blocked . If on a single processor , Only one thread can run at a time , And it just needs one LWP That's enough , but I/O Intensive applications may require multiple LWP To execute .

A communication method between the user thread library and the kernel is Scheduler Activations (scheduler activation), The kernel provides a set of virtual processors (LWP) Feed the application , Applications can schedule user processes to an available virtual processor .

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

版权声明
本文为[The struggling rabbit of florist]所创,转载请带上原文链接,感谢

Scroll to Top