Operating System Concepts Learning Note 9 threads

Source: Internet
Author: User
Tags posix signal handler terminates

Operating System Concepts Learning Note 9 Thread overview

A single process can include multiple control threads.

Thread--a basic unit of CPU utilization, which is the basis of forming multi-threaded computer.

A thread is the basic unit used by the CPU and consists of a thread ID, a program counter, a collection of registers, and a stack. It shares code snippets, data segments, and other operating system resources with other threads that belong to the unified process.

A traditional heavyweight process has only a single control thread, and if the process has multiple control threads, it can do multiple tasks at the same time.

Single thread and multi-threaded

Motivation

An application is typically implemented as a standalone process with multiple control threads. If a busy Web server has more than one (or thousands of) clients accessing it concurrently, multiple threads can be established rather than processes, because the creation process is time consuming and the process of a single thread can only process one request at one time.

Threads also play an important role in remote procedure call (RPC) systems, and typically, the PRC server is multithreaded. When a server receives a message, it uses a separate thread to process the message, which allows the server to handle multiple concurrent requests.

Many modern operating systems are multi-threaded, with a few threads running in the kernel, with each thread completing a specified task.

Advantages of multithreading
    1. High responsiveness: even if it partially blocks or performs a lengthy operation, the program can continue to execute, increasing the corresponding degree to the user.

    2. resource sharing: threads By default 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 different active threads in the same address space.

    3. Economy: The allocation of memory and resources required for process creation is more expensive. Because threads can share the resources of the processes they belong to, it is more economical to create and switch threads.

    4. leveraging multi-processor architectures: One of the advantages of multithreading is the full use of multiprocessor architectures. So that each process can run on a different processor in parallel. No matter how many CPUs there are, single-threaded processes can only run on one CPU, and multithreading on multiple CPUs enhances concurrency.

Multithreaded models:

There are two different ways to provide threading support: A user-level user thread and a kernel-layer kernel thread . User threads are supported by the kernel without kernel management, while kernel threads are supported and managed by the operating system. In fact, all contemporary operating systems support kernel threads. There must be a relationship between the user thread and the kernel thread.

Many-to-one model:

Many-to-one models map many user-level threads to a kernel thread. Thread management is performed by line libraries in user space and is therefore more efficient. However, if a thread executes a blocking system call, the entire thread blocks. Because only one thread can access the kernel at any time, multiple threads cannot run on multiple processors in parallel.

One-to-one model:

Each user thread maps to a single kernel thread. The model allows another thread to continue executing while one thread is executing a blocking system call. It also allows multiple threads to run in parallel on multiprocessor systems, the only disadvantage of which is that each user thread created creates a corresponding kernel thread. Because the overhead of creating kernel threads can affect the performance of your application, the vast majority of implementations of this model limit the number of threads supported by the operating system.

Many-to-many models:

Many-to-many models multiplexed a number of user threads onto the same number or a smaller number of kernel threads. Many-to-many models do not have the disadvantage of both: developers can create as many user threads as possible, and the corresponding kernel threads can execute concurrently on multiprocessor systems. And when a thread executes a blocking system call, internal nuclear power dispatches another thread to execute.

A variant of the popular many-to-many model still takes many user threads to the same number or a smaller number of kernel threads, but also allows a user thread to be bound to a kernel thread. This variant has been called a two-level model.

Thread Library): Provides an API for programmers to create and manage threads. There are two main ways to achieve line libraries.

(1) A library with no kernel support is provided in the user space, and all the code and data structures of this library are present in the user space. Calling a function knowledge in the library causes a local function call in user space, not a system call.

(2) Execute a kernel-level library with the direct support of the operating system. At this point, the library's code and data structure exist in the kernel space. Calling an API function in the library typically results in system calls to the kernel.

The three main line libraries currently in use are:

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

Pthread as a POSIX standard extension, you can provide a user-level or kernel-level library. The Win32 line libraries is a kernel-level line libraries for the Windows operating system. The Java Threading API allows threads to be created and managed directly in a Java program. However, because most JVM instances run on top of the host operating system, the Java Threading API is typically implemented using line libraries on the host system.

Pthread

Pthread is an API that is defined by the POSIX standard for threading creation and synchronization. This is the specification of the threading behavior, not the implementation. The operating system designer can take any form to be implemented as desired.

All pthread programs need to include pthread.h header files.

Pthread_t Tid declares the identifier for the common thread. Each thread has a set of properties, including the stack size and scheduling information.

pthread_attr_t attr represents the properties of a thread and is set by a function call Pthread_attr_init (&ATTR).

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

Pthread_join () function waits

Pthread_exit () completed

Pthread Instance Program:

The following sample lab program implements a concurrent two-thread collaboration that adds the value of integer X from 1 to 10
Yes. They send the results to each other through pipelines.

/** description:tpipe.c* Copyright: (c) by Roland Sun * Function: Using a pipeline to pass integers between threads */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <pthread.h>voidTask1 (int*);//thread 1 performs function prototypesvoidTask2 (int*);//Thread 2 performs function prototypesintpipe1[2],pipe2[2];//Storage of two nameless pipe markingspthread_t Thrd1,thrd2;//Storage of two thread IDsintMainintargcChar*arg[]) {intRetintnum1,num2;//using a pipe () system call to build two nameless pipes. Establishment of unsuccessful program exit, execution terminationif(Pipe (PIPE1) <0) {perror ("Pipe not create");Exit(exit_failure);}if(Pipe (PIPE2) <0) {perror ("Pipe not create");Exit(exit_failure);}Two threads are established using the Pthread_create system call. Establishment of unsuccessful program exit, execution terminationNUM1 =1; ret = Pthread_create (&thrd1,null, (void*) Task1, (void*) &AMP;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 threadPthread_join (Thrd2,null);//suspend current thread switch to THRD1 threadPthread_join (Thrd1,null);Exit(exit_success);}//thread 1 executes the function, which first writes to the pipe and then reads from the pipevoidTask1 (int*num) {intx=1;//Each loop writes the value of the variable x to the 1 end of pipe 1, and from//Pipe 2 0 End Read an integer write x plus 1 for x, until x is greater than 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 is complete, close the pipeClose (pipe1[1]); Close (pipe2[0]);}//thread 1 executes the function, which first reads from the pipe and then writes to the pipevoidTask2 (int* num) {intX//Each loop reads an integer from the 0 end of the pipe 1 into the variable x,//And write to the 1 end of pipe 2 after x plus 1 until x is greater than 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 is complete, close the pipeClose (pipe1[0]); Close (pipe2[1]);}

Operation Result:

Sora@sora: ~/sora/program/pthread$ Gcc-g-C Demo.csora@sora: ~/sora/program/pthread$ GCC demo.o-l pthread-o Demosora@sora: ~/sora/program/pthread$ ./demo Thread1read: 1Thread2read: 2Thread1read: 3Thread2read: 4Thread1read: 5Thread2read: 6Thread1read: 7Thread2read: 8Thread1read: 9Thread2read: Ten
Win32 Threads

Win32 Line Libraries creates threading technology in some ways similar to pthread technology.

Win32 Thread: Win32 API must include Windows.h header file

Thread creation uses CreateThread () to pass the properties of a set of threads to this function.

The Pthread_join () statement implemented in the Pthread program implements thread waits, and the equivalent function WaitForSingleObject () is used in Win32 to block the creator thread.

Java Threads

Java Threads: Threads are the basic model of program execution in Java programs.

All Java programs have at least one control thread, even a simple Java program with a main () function that runs as a thread in the JVM.

There are two techniques for creating threads in Java programs.

(1) Create a new class that derives from the thread class and overloads its run () function.

(2) Define a class that implements the Runnable () interface. When a class executes runnable (), he must define the run () function, and the code implementing the Run () function is executed as a separate thread.

Creating a thread pair does not create a new thread, it actually creates a new thread with the start () function. Calling the start () function for a new object requires two things:

One is to allocate memory in the JVM and initialize the new thread;

The second is to call the run () function, which implements the thread for running in the JVM.
(Note that you never directly tune the run () function, but instead call the start () function, and then it calls the run () function).

There is a join () function in Java corresponding to Pthread_join ().

Three comparisons:

Sharing data in Win32 and Pthread is convenient, and you can simply declare shared data as global data. For Java, there is no global data concept, in Java programs if two or more threads need to share data, by passing a reference to the shared object to the appropriate thread.

Multithreading problem system calls fork () and exec ()

In multithreaded programs, the semantics of the system call Fork () and exec () change.

If a process in the program calls Fork (), does the new process replicate all threads, or does the new process have only a single thread? Some UNIX systems have two forms of fork (), one to replicate all threads, and the other to replicate only those threads that call the system call Fork ().

EXEC () works: If a thread calls the system to call EXEC (), the program specified by the EXEC () parameter replaces the entire process, including all threads.

If you call EXEC () immediately after calling fork (), it is not necessary to copy all the threads because the program specified by the EXEC () parameter replaces the entire process. In this scenario, only the calling thread that is copied is more appropriate. However, if another process does not call EXEC () after the fork (), then the other process should replicate all processes.

Cancel

thread cancellation is a task that terminates a thread before it is finished.

The thread to be canceled is often referred to as the target thread . Cancellation of the target thread can occur in the following two scenarios:

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

The second is delay cancellation (deferred cancellation): The target thread constantly checks whether it should terminate, which allows the target thread to have an opportunity to terminate itself in an orderly manner.

If a resource is already assigned to a thread to be canceled, or if the thread being canceled is updating data that is shared with other threads, then cancellation can be difficult and is especially troublesome for asynchronous cancellation. The operating system reclaims system resources that cancel threads, but typically does not reclaim all resources. Therefore, asynchronously canceling a thread does not make the required system resources idle. Conversely, when deferred cancellation is used, a thread is allowed to check if it is canceled at a secure point, pthread calls these points a cancellation point (cancellation points)

Signal Processing

Signal Processing: The signal is used in UNIX to inform the process that a particular time has occurred and the signal can be received synchronously or asynchronously. All signals have the same pattern:

(1) The occurrence of a specific occurrence of a signal

(2) The generated signal is sent to the process

(3) Once sent, the signal must be traded for processing.

Examples of synchronous signals include accessing illegal memory or being removed by 0. In this case, if the program executes these actions, then a signal is generated, and the synchronization signal is sent to the same process that generated the signal to perform the operation (the reason for synchronization).

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

Each signal may be handled by one of two possible handlers:

(1) Default signal processing program

(2) User-defined signal processing program

Each signal has a default signal handler that, when the processing signal is run in the kernel, can be rewritten with a user-defined signal handler. Signals can be handled in different ways. Some signals can be simply ignored (such as changing the window size), and some need to terminate the program to handle (illegal memory access)

The signal processing of a single-threaded procedure is more straightforward and the signal is always sent to the process.

When multi-threading, the signal is

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

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

(3) Send a signal to some fixed thread within the process

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

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

Most threaded UNIX allows threads to describe what signals it receives and what signals it rejects. , because a signal can only be processed once, so the signal is usually sent to the first thread that does not reject it.

Pthread also provides the Pthread_kill function, which allows the limit number to be passed to a specified thread.

Windows simulates a signal through an asynchronous procedure call (asynchronous procedure CALL,APC).

Thread pool

A multithreaded server has some potential problems: the first is about the time it takes to create a thread before the request is processed, and the fact that the thread is discarded after it has finished working. Second, if all concurrent requests are allowed to be handled by a new thread, there is no way to limit the number of threads that execute concurrently in the system. Unlimited threads can drain system resources. The solution to this problem is to use a thread pool.

The idea of the thread pool is to create a certain number of threads at the beginning of the process and put them into the pool to wait for work. When the server receives the request, he wakes up a thread in the pool and passes the request to him, and once the thread finishes the service, it returns to the pool waiting to work. If there are no threads available in the pool, the server waits until there are empty threads.

Benefits of the thread pool:

(1) It is usually faster to process a request with an existing thread than to wait for a new thread to be created

(2) The thread pool limits the number of threads available at any time.

The number of threads in the thread pool is determined by the number of system CPUs, the size of the physical memory, and the expected value of concurrent client requests. The more advanced thread pool can dynamically adjust the number of threads to suit the situation.

Thread-specific data

Threads that belong to one process share process data.

In some cases, each thread may require its own copy of the data, which is called thread-specific data . You can have each thread associated with its unique identifier.

Scheduler activation

The problem of communication between kernel and line libraries is to discuss many-to-many models. This coordination allows the number of kernel threads to be dynamically adjusted to ensure their best performance.

Set up an intermediate data structure between the user kernel threads. Lightweight process (LWP), he is represented as an application that can dispatch user threads to run virtual processors. Each LWP is connected to the kernel thread, which is dispatched by the operating system to the physical processor, and if the kernel thread is blocked, the LWP is blocked and the user thread connected to the LWP is blocked. If you can only run one thread at a time on a single processor, you need only one LWP, but an I/O intensive application may require more than one LWP to execute.

An end-user line the method of communication between the libraries and the kernel is the Scheduler activation (scheduler activation), which provides a set of virtual processors (LWP) to the application, which dispatches the user process to an available virtual processor.

Operating System Concepts Learning Note 9 threads

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.