Difference between processes and threads (emphasis)

Source: Internet
Author: User
Tags time in milliseconds
ArticleDirectory
    • 5.1 Introduction
    • Process 5.2
    • Thread 5.3
    • 5.4 introduction to resource access Synchronization
    • 5.4.2 deadlock
    • 5.5 use the volatile field to synchronize with the interlocked class
    • 5.6 use the lock keyword of the system. Threading. Monitor class and C # for synchronization

Source: http://www.cnblogs.com/lmule/archive/2010/08/18/1802774.html

 

In short,ProgramThere is at least one process, and one process has at least one thread.
The thread division scale is smaller than the process, making the multi-thread program highly concurrent.
In addition, the process has independent memory units during execution, and multiple threads share the memory, which greatly improves the program running efficiency.
The execution process of a thread is different from that of a process. Each Independent thread has a program running entry, sequence execution sequence, and program exit. But the thread cannot be executed independently. It must exist in the application and the application provides multiple thread execution control.
Logically, multithreading means that multiple execution parts in an application can be executed simultaneously. However, the operating system does not view multiple threads as multiple independent applications to implement process scheduling, management, and resource allocation. This is an important difference between processes and threads.

A process is a running activity of a program with certain independent functions. A process is an independent unit for the system to allocate and schedule resources.
A thread is an entity of a process. It is the basic unit for CPU scheduling and scheduling. It is smaller than a process and can run independently. the thread itself basically does not have system resources, and only has a few resources (such as program counters, a set of registers and stacks) that are essential for running ), however, it can share all resources of a process with other threads of the same process.
One thread can create and cancel another thread, and multiple threads in the same process can be concurrently executed.

The main difference between processes and threads is that they are different operating system resource management methods. A process has an independent address space. After a process crashes, it does not
The thread is only a different execution path in the process. The thread has its own stack and local variables, but there is no separate address space between the threads. If a thread dies, the whole process will die.
Program is more robust than multi-threaded programs, but it consumes a lot of resources and is less efficient during process switching. But for concurrent operations that require simultaneous sharing of certain variables, you can only use threads, not
Process. If you are interested, I suggest you take a look at the modern operating system or the design and implementation of the operating system. Make it clear about the problem.

5.1 Introduction

A process is a memory area that contains certain resources. The operating system uses a process to divide its work into some functional units.

One or more execution units contained in a process are called threads ). A process also has a private virtual address space that can only be accessed by the threads it contains.

When a. Net program is run, the process also includes the software layer called CLR into its memory space. The previous chapter described CLR in detail. This software layer is loaded by the runtime host during process creation (see section 4.2.3 ).

A thread can belong to only one process and can only access the resources of the process. After the operating system creates a process, the process automatically requests a thread named as the main thread or the first thread. The main thread will run the runtime host, while the runtime host will load the CLR.

An application is composed of one or more collaborative processes. For example, the Visual Studio development environment is an application that uses one process to edit the source file and another process to complete compilation.

In Windows NT/2000/XP, we can view all applications and processes at any time through the task manager. Although only several applications are opened, about 30 processes usually run simultaneously. In fact, the system executes a large number of processes to manage the current sessions, taskbar, and other tasks.

5.2 process 5.2.1 Introduction

In a 32-bit Windows operating system running on a 32-bit processor, a process can be considered as a 4 GB (232 bytes) linear memory space, it starts at 0x00000000 and ends at 0 xffffff. This memory space cannot be accessed by other processes, so it is called the private space of this process. The space is divided into two parts. 2 GB is owned by the system, and 2 GB is owned by the user.

If N processes run on the same machine, n × 4 GB of Ram is required. Fortunately, this is not the case.

    • In Windows, memory is allocated for each process as needed, and 4 GB is the maximum space occupied by a process in a 32-bit system.
    • Divide the memory required by the process into 4 kb memory pages, and store these memory pages on the hard disk or load them into RAM according to the usage. Through the system's virtual memory mechanism, we can effectively reduce the actual memory demand. Of course, these are transparent to users and developers.
5.2.2 system. Diagnostics. Process class

An instance of the system. Diagnostics. Process class can reference a process. The referenced process contains the following types.

    • The current process of the instance.
    • Other processes except the current process on the local machine.
    • A process on a remote machine.

Through the methods and fields contained in this class, you can create or destroy a process and obtain information about a process. The following describes some common tasks that are implemented using this class.

5.2.3 create and destroy sub-Processes

The following program creates a new process called a sub-process. In this case, the initial process is called the parent process. The child process starts a notepad application. The thread of the parent process destroys the child process after waiting for 1 second. The execution result of this program is to open and close notepad.

Example 5-1

The static method start () can use the existing Windows File Extension association mechanism. For example, we can use the followingCodePerform the same operation.

By default, a child process inherits the security context of its parent process. However, you can also use an overloaded version of the process. Start () method to start this sub-item in any user's security context.
Process, of course, you need to provide the user name and password through an instance of the system. Diagnostics. processstartinfo class.

5.2.4 avoid running multiple instances of the same application on one machine at the same time

Some applications require this function. In fact, it is meaningless to run multiple instances of an application on the same machine at the same time.

Until now, to meet the preceding constraints in windows, the most common method for developers is to use the named mutex technology (see section 5.7.2 ). However, using this technology to meet the above constraints has the following Disadvantages:

    • This technology has a small and potential risk of making the mutex name used by other applications. In this case, this technology will no longer be effective and will cause bugs that are hard to detect.
    • This technology cannot solve the general problem of allowing only one application to generate n instances.

Fortunately, the system. Diagnostics. Process class has static methods such as getcurrentprocess () (returns the current process) and getpro-cesses () (returns all processes on the machine. In the following program, we have found an elegant and simple solution for the above problems.

Example 5-2

After the name of the remote machine is specified by the method parameter, the getprocesses () method can also return all processes on the remote machine.

5.2.5 terminate the current process

You can call the static method exit (int
Exitcode) or failfast (stringmessage) to terminate the current process. The exit () method is the best choice. It will completely terminate the process and return
The exit code value. The reason for this is that all the cleanup work of the current object and the execution of finally blocks will be completed by different threads. Of course, it takes some time to terminate the process.

As the name suggests, the failfast () method can terminate the process quickly. The preventive action taken by the exit () method will be ignored by it. Only one serious error containing the specified information is recorded in the log by the operating system. You may want to use this method when exploring the problem, because the complete termination of the program can be considered as the cause of Data deterioration.

5.3 thread 5.3.1 Introduction

A thread contains the following content.

    • A pointer to the currently executed command;
    • One stack;
    • A set of register values that define some values that describe the processor status of the executing thread;
    • A private data zone.

All these elements belong to the thread execution context. All threads in the same process can access the address space contained by the process, and of course all the resources stored in the space.

We are not going to discuss the issue of thread execution in kernel mode or user mode. Although. net has been used in earlier windows and still exists, they are invisible to. NET Framework.

Parallel use of some threads is usually implementedAlgorithm. In fact, an algorithm is usually composed of a series of tasks that can be executed concurrently. However, it should be noted that the use of a large number of threads will lead to too many context switches, but ultimately affects the performance.

A few years ago, we noticed that Moore's Law, which predicts a doubling of the processing speed every 18 months, is no longer true. The frequency of the processor stops at 3 GHz ~ 4 GHz. This is because the physical
It takes some time to make a breakthrough. At the same time, in order to remain competitive in performance, large processor manufacturers such as AMD and Intel are currently turning their targets to multi-core chips. So we can
This type of architecture is expected to be widely used in the next few years. In this case, the only solution to improve application performance is to make rational use of multithreading technology.

5.3.2 managed threads and Windows threads

You must understand that the thread for executing the. NET application is actually a Windows Thread. However, when a thread is known to CLR, it is called a managed thread. Specifically
The thread created by the managed code is the managed thread. If a thread is created by an unmanaged code, it is an unmanaged thread. However, once the thread executes the managed code, it becomes
Managed threads.

The difference between a managed thread and a non-managed thread is that CLR will create an instance of the system. Threading. Thread class to represent and operate the former. In internal implementation, CLR stores a list Of all managed threads in a place called threadstore.

CLR ensures that every managed thread is executed in an appdomain at any time, but this does not mean that a thread will always be in an appdomain, it can be transferred to another appdomain over time. For the concept of appdomain, see 4.1.

From a security perspective, the primary user of a managed thread is irrelevant to the Windows primary user in the underlying unmanaged thread.

5.3.3 preemptible multitasking

We can ask ourselves the following question: My computer has only one processor, but in the task manager we can see that hundreds of threads are running on the machine at the same time! How is this possible?

Thanks to preemptible multi-task processing, the scheduling of threads makes the above problem possible. As a part of the Windows Kernel, the scheduler splits time slices into time slice segments. This
The time interval is accurate in milliseconds and the length is not fixed. For each processor, each time slice serves only one thread. The rapid execution of threads creates the illusion that they are running simultaneously. We have two
Perform context switching during the interval of time slice. The advantage of this method is that threads waiting for some windows resources will not waste time slice until the resources are valid.

The preemptible adjective is used to modify the multitasking management mode because the thread is forcibly interrupted by the system. Those who are curious about this should understand that, in context switching
During the process, the operating system inserts a command to jump to the next context switch in the code to be executed by the next thread. This command is a soft interrupt. If the thread terminates before this command (for example,
It is waiting for a resource), then the specified will be deleted, and context switching will also happen in advance.

The main disadvantage of preemptible multitasking is that a synchronous mechanism must be used to protect resources to avoid unordered access. In addition, there is another multitasking management model called coordinated multitasking.
Management, in which the switch between threads will be completed by the thread itself. This model is generally considered too dangerous because it is too risky to switch between threads. As described in section 4.2.8
This mechanism is used internally to improve the performance of some servers, such as SQL server2005. However, Windows only supports preemptible multitasking.

5.3.4 priority of processes and threads

Some tasks have a higher priority than others, and they require the operating system to apply for more processing time for them. For example, some peripheral drives under the master processor must not be interrupted. Another type of high-priority task is the graphic user interface. In fact, users do not like to wait for the UI to be re-painted.

Users from the Win32 world know that each thread can be assigned a value of 0 ~ Priority of 31. However, you cannot use these values in the. NET world because:

    • They cannot describe their own meaning.
    • These values are very easy to change over time.

1. Process Priority

You can use the priorityclass {Get; set;} attribute of processpriorityclass in the process class to give the process a priority. System. Diagnostics. processpriorityclass enumeration contains the following values:

If the value of the priorityboostenabled attribute of the Process class is true (the default value is true), the priority of a process increases by one unit when it occupies the foreground window. This attribute can be accessed only when an instance of the Process class references a local process.

You can use the task manager to change the priority of a process: Right-click the selected process and choose set priority from the six values provided (the same as described.

In Windows, there is a idle process with a priority of 0. This process cannot be used by any other process. According to the definition, the activity of a process is expressed as a percentage of time: 100% minus the time consumption rate in idle processes.

2. thread priority

Each thread can combine the priority of the process to which it belongs, and use
Priority {Get; set;} attributes define their respective priorities. System. Threading. Thread-priority contains the following enumerated values:

In most applications, you do not need to modify the priority of processes and threads. Their default values are normal.

5.3.5 system. Threading. Thread class

CLR automatically associates an instance of the system. Threading. Thread class with various managed threads. You can use this object from the thread itself or from other threads.
Manipulate the thread. You can also obtain the object of the current thread through the static attribute currentthread of the system. Threading. Thread class.

The thread class has a function that allows us to easily debug multi-threaded applications. This function allows us to use a string to name a thread:

5.3.6 create and join a thread

You only need to create a Thread class instance to create a new thread in the current process. This class has multiple constructors, And they will accept a type
System. Threading. threadstart or system. Threading. parame-trizedthreadstart
The entrusted object is used as a parameter. After the thread is created, the method referenced by the delegate object is first executed. Use a delegate object of the parametrizedthreadstart type to allow users to use a new thread.
The method to be executed is passed into an object as a parameter. Some constructors of the thread class also accept an integer parameter to set the maximum stack size to be used by the thread. The value must be at least KB (that is
131072 bytes ). After a thread-type instance is created, the thread. Start () method must be called to start the thread.

Example 5-3

Program output:

In this example, we use the join () method to suspend the current thread until the thread that calls the join () method has completed execution. This method also contains an overloaded version containing parameters. The parameters are used
Specifies the maximum time (that is, timeout) of the waiting thread to end in milliseconds. If the thread stops working within the specified timeout period, the join () method of this version returns a Boolean value of true.

5.3.7 suspend a thread

You can use the sleep () method of the thread class to suspend a running thread for a specific period of time. You can also use an integer value in milliseconds or
The instance of the system. timespan structure sets the suspension time. An instance of this structure can be set to a precision of 1/10
MS (100ns) time period, but the sleep () method has the highest accuracy of only 1 ms.

We can also use the suspend () method of the thread class to suspend the activity of a thread from the thread itself or another thread. In both cases, the thread will be blocked.
Until the resume () method is called by another thread. Compared with the sleep () method, the suspend () method does not immediately suspend the thread, but arrives at the next security point of the thread.
Then the CLR suspends the thread. For the concept of security points, see section 4.7.11.

5.3.8 terminate a thread

A thread can terminate itself in the following scenarios.

    • Exit from the method (main () method in the main thread and the method referenced by the threadstart delegate object in other threads) that you start to execute.
    • Terminated by yourself.
    • Terminated by another thread.

The first case is not very important. We will focus on the other two cases. In both cases, you can use the abort () method (either through the current thread or a thread other than the current thread ). Use
This method will cause an exception of the threadabortexception type in the thread. Because the thread is in a special State called abortrequested
An exception has a special feature: when it is caught by exception handling, it is automatically thrown again. Only when thread. resetabort () is called in exception handling (if we
To prevent its propagation.

Example 5-4 active thread suicide

When thread a calls the abort () method to thread B, it is recommended to call the join () method of B so that a waits until B terminates. The interrupt () method can also
The thread in the blocking status (that is, the thread is terminated because one of the wait (), sleep (), or join () methods is called. This method is used to indicate whether the thread to be terminated is in the blocking status.
Different behaviors.

    • If the thread to be terminated is blocked when the method is called by another thread, a threadinterruptedexception exception occurs.
    • If the method is called by another thread and the thread to be terminated is not blocked, an exception is thrown once the thread is blocked. This behavior is the same as that when the thread calls the interrupt () method on its own.
5.3.9 foreground and background threads

The thread class provides the Boolean attribute of isbackground {Get; Set. When the current thread is still running, it will prevent the process from being terminated. On the other hand
If there are no foreground threads in the process, the background thread will be automatically terminated by CLR (call the abort () method ). The default value of isbackground is false, which means that all threads are default.
The status is in the foreground.

5.3.10 status chart of managed threads

The thread class has a threadstate field of the system. Threading. threadstate Enumeration type, which contains the following enumerated values:

You can find the specific description of each status in the previous article "threadstateenumeration" on msdn. This enumeration type is a binary field.
Indicates that an instance of this type can simultaneously represent multiple enumerated values. For example, a thread can be in the running, abortrequested, and background state at the same time.
Status. For the concept of binary fields, see section 10.11.3.

Based on the knowledge we have learned in the previous section, we have defined the simplified state chart 5-1.

Figure 5-1 Simplified managed thread status

5.4 introduction to resource access Synchronization

The word "Synchronize" is used in the computing of multi-threaded applications (one or more processors. In fact, these applications have multiple execution units, which are used to access resources.
Conflicts may occur. The synchronization objects are shared among threads, and the synchronization object aims to block one or more threads until another thread satisfies a specific condition.

We will see that there are a variety of synchronization classes and synchronization mechanisms, each system for one or more specific needs. To use synchronization to build a complex multi-threaded application, it is necessary to master the contents of this chapter. We will try our best to differentiate them in the following content, especially to point out the most subtle differences between various mechanisms.

Reasonably synchronizing a program is one of the most elaborate software development tasks. A single topic is enough to write several books. Before going into the details, you should first check whether synchronization is inevitable. Generally, some simple rules can keep us away from synchronization issues. There are affinity rules for threads and resources in these rules. We will introduce them later.

We should be aware that the difficulty in synchronizing access to resources in the program comes from the dilemma of using fine-grained locks or coarse-grained locks. If you use coarse-grained synchronization when accessing resources
It can simplify the code, but it will also expose itself to the contention bottleneck. If the granularity is too small, the code will become very complicated, so that the maintenance work is annoying. Then we will encounter deadlocks and race conditions.
This topic describes the issues.

Therefore, before talking about the synchronization mechanism, it is necessary to first understand the concept of race conditions and deadlocks.

5.4.1 competitive conditions

A race condition refers to a special situation in which each execution unit executes an action in an order without logic, leading to unexpected results.

For example, after the thread t modifies the resource R, it releases its write access to R, and then re-obtains the read access to R to use it, I thought it was still in the State after it was released. However, after the write access is released, the R state may be modified by another thread during the interval from re-obtaining the read access.

Another typical example of competing conditions is the producer/consumer model. The producer usually uses the same physical memory space to save the information produced. In general, we will not forget that
To protect the space between concurrent accesses. What is easy to forget is that the producer must ensure that the old information has been read by the consumer before new information is produced. If we do not take the corresponding preventive measures, we will face
The risk that production information is never consumed.

If the static conditions are not properly managed, security system vulnerabilities may occur. Another instance of the same application may trigger a series of events that developers cannot predict. Generally
The Boolean write access used to confirm the identity authentication result is the most perfect protection. If this is not done, after its status is set by the identity authentication mechanism, it will be read to protect access to resources.
. Many known security vulnerabilities are attributed to improper management of static conditions. One of them even affects the kernel of the UNIX operating system.

5.4.2 deadlock

A deadlock occurs when two or more execution units wait for each other to finish. For example:

A thread T1 obtains access to resource R1.

A thread T2 obtains access to resource R2.

T1 requests access to r2. however, T2.

T2 requests access to R1 but has to wait because this power is occupied by T1.

T1 and t2 will remain in the waiting state forever. At this time, we are in a deadlock situation! This problem is more confidential than most of the bugs you encounter. There are three solutions to this problem:

    • One thread is not allowed to access multiple resources at the same time.
    • Define a relational order for obtaining resource access permissions. In other words, when a thread has obtained access to R1, it cannot obtain access to r2. Of course, the release of access rights must follow the opposite order.
    • Define a maximum wait time (timeout) for all requests that access resources, and properly handle request failures. Almost all. Net synchronization devices provide this function.

The first two technologies are more efficient but more difficult to implement. In fact, they all require strong constraints, which will become increasingly difficult to maintain as applications evolve. However, using these technologies will not fail.

A large project usually uses the third method. In fact, if a project is large, it generally uses a large amount of resources. In this case, the probability of conflicts between resources is very low, which means that failure is rare. We think this is an optimistic method. With the same spirit, we described an optimistic database access model in section 19.5.

5.5 use the volatile field and interlocked class to synchronize the 5.5.1 volatile field

The volatile field can be accessed by multiple threads. We assume that these accesses are not synchronized. In this case, some internal mechanisms in CLR for managing code and memory will be responsible for synchronization
But it cannot ensure that the read access to this field can always read the latest value, and the field declared as volatile can provide such a guarantee. In C #, if a field is used before its declaration
The volatile keyword is declared as volatile.

Not all fields can be volatile and there is a condition for such fields. If a field is to be volatile, it must be of the following types:

    • Reference Type (only the referenced access to this type is synchronized, And the accessed members are not synchronized ).
    • A pointer (in an insecure code block ).
    • Sbyte, byte, short, ushort, Int, uint, Char, float, and bool (double, long, And ulong when operating on a 64-bit processor ).
    • An Enumeration type that uses the following underlying types: byte, sbyte, short, ushort, Int, and uint (double, long, And ulong when operating on a 64-bit processor ).

You may have noticed that only the type of value or referenced number of digits that do not exceed the number of digits of the native integer value (4 or 8 is determined by the underlying processor) can become volatile. This means that concurrent access to a larger value type must be synchronized, which will be discussed below.

5.5.2 system. Threading. Interlocked class

Experience shows that resources that need to be protected under multi-thread conditions are generally integer values, and the most common operations for these shared integer values are increase/decrease and
Add .. Netframework uses the system. Threading. Interlocked class to provide a dedicated mechanism for completing these specific operations. This class
Three static methods, increment (), decrement (), and add (), are used to increment, decrease, and add the Int or long type variables.
The parameter is passed in as a reference. We think that using the interlocked class makes these operations atomic.

The following program shows how two threads concurrently access an integer variable named counter. One thread increments it five times, and the other increments it five times.

Example 5-5

Output of the Program (output in an uncertain way, meaning that the results displayed every execution time are different ):

If we do not allow these threads to sleep for 10 milliseconds after each variable modification, they will have enough time to complete their tasks in a single time segment, so that there will be no cross operations, not to mention concurrent access.

5.5.3 other functions provided by the interlocked class

The interlocked class also allows the exchange () Static Method to exchange the status of certain variables in the form of atomic operations. You can also use the compareexchange () Static Method to exchange two values in the form of atomic operations when a specific condition is met.

5.6 use the lock keyword of the system. Threading. Monitor class and C # for synchronization

It is undoubtedly very important to complete simple operations with atomic operations, but this is far from covering all the cases that require synchronization. The system. Threading. Monitor class allows almost any piece of code to be executed by only one thread at a certain time. We call this code a critical section.

5.6.1 enter () and exit () Methods

The monitor class provides two static methods: enter (object) and exit (object. These two methods take an object as a parameter, which provides a simple
A single method is used to uniquely identify the resource that will be accessed in synchronous mode. When a thread calls the enter () method, it waits for exclusive access to the referenced object (only when the other thread has this permission)
). Once the power is obtained and used, the thread can call the exit () method on the same object to release the power.

A thread can call enter () multiple times for the same object, and only needs to call exit () of the same number of times for the same object to release exclusive access.

A thread can also have exclusive permissions on multiple objects at the same time, but this will lead to deadlocks.

You must not call the enter () and exit () methods for a value-type instance.

No matter what happens, you must call exit () in the finally clause to release all the exclusive access permissions.

In Example 5-5, if one thread has to square the counter once and the other thread has to multiply the counter by 2, we have to replace the interlocked class with the monitor class. The code for F1 () and F2 () will become as follows:

Example 5-6 [1]

It is easy to think of counter instead of typeof (Program), but counter is a static member of the value type. Note that the sum of squares and doubling operations do not meet the exchange law, so the final result of counter is non-deterministic.

The lock keyword of 5.6.2 C #

The C # language provides a simpler choice by using the lock keyword than using the enter () and exit () methods. Our program can be rewritten as follows:

Example 5-7

Like the for and if keywords, if the block defined by the lock keyword contains only one instruction, curly brackets are no longer needed. We can rewrite it:

Use the lock keyword to guide the C # compiler to create a try/Finally block, so that any possible exceptions can still be expected. You can use the reflector ildasm.exe tool to verify this.

5.6.3 syncroot Mode

Like the previous example, we usually use the monitor class in a static method with a type instance. Similarly, we often use this key in a non-static method.
To achieve synchronization. In both cases, we synchronize ourselves through an object that is externally visible to the class. If other parts of the Code also use these objects to achieve their own synchronization, the problem may occur. Is
To avoid this potential problem, we recommend that you use a private member named syncroot of the object type. It depends on whether the Member is static or non-static.

Example 5-8

The system. Collections. icollection interface provides the object-type syncroot {Get;} attribute. Most collection classes
(Generic or non-generic) all implement this interface. Similarly, you can use this attribute to synchronize access to elements in the set. However, the syncroot mode is not actually applied here, because
The objects used for row synchronization are not private.

Example 5-9

5.6.4 thread security

If each instance of a class cannot be accessed by more than one thread at a time, this class is called a thread-safe class. To create a thread-safe class, you only need
The syncroot mode is applied to the methods it contains. If a class wants to become thread-safe and does not want to add too much burden to the Code in the class, a good way is to provide
Inheritance class encapsulated by thread security.

Example 5-10

Another method is to use system. runtime. remoting. contexts. synchronizationattribute, which will be discussed later in this chapter.

5.6.5 monitor. tryenter () method

This method is similar to enter (), except that it is non-blocking. If the exclusive access to the resource has been occupied by another thread, this method immediately returns a false return value. We can also
Call the tryenter () method to block a period of time in milliseconds. Because the returned results of this method are not determined and must be in the finally clause after obtaining the exclusive access
Release this power, so it is recommended to immediately exit the function being called when tryenter () fails:

Example 5-11 [2]

5.6.6 the wait () method of the monitor class, the pulse () method, and the pulseall () method

The wait (), pulse (), and pulseall () methods must be used together and combined with a small scenario to be correctly understood. Our idea is as follows: a thread obtains
And it decides to wait (by calling wait () until the state of the object changes. To this end, the thread must temporarily lose the exclusive access to the object so that another thread can repair it.
Modify the object status. The thread that modifies the object state must use the pulse () method to notify the thread that waits for the modification to complete. The following is a small scenario to illustrate this situation.

    • When a T1 thread has exclusive access to the OBJ object, call the wait (OBJ) method to register it to the passive wait list of the OBJ object.
    • Because of the above calls, T1 loses its exclusive access to OBJ. Therefore, the other thread T2 obtains the exclusive access to OBJ by calling enter (OBJ.
    • T2 finally changed the OBJ status and called pulse (OBJ) to notify the change. This call will cause OBJ to passively wait for the first thread in the list (T1 here) to be moved
      OBJ actively waits for the first place in the list. Once the exclusive access permission of obj is released, OBJ takes the initiative to wait for the first thread in the list to be ensured to obtain the permission. Then it starts from the wait (OBJ) Method
      .
    • In our scenario, T2 calls exit (OBJ) to release exclusive access to OBJ, T1 restores access and exits from the wait (OBJ) method.
    • Pulseall () transfers all threads in the passive wait list to the active wait list. Note that these threads will arrive at the non-blocking state in the order they call wait.

If wait (OBJ) is called by a thread that has called enter (OBJ) multiple times, the thread will need to call exit (OBJ) of the same number of times to release access to OBJ. Even in this case, one pulse (OBJ) call by another thread is enough to change the first thread to a non-blocking state.

The following program uses the access permission of a ball object in an alternate way through the Ping and Pong threads to demonstrate this function.

Example 5-12

Output by the Program (in an uncertain way ):

The Pong thread has not ended and is still blocked on the wait () method. Because the pong thread is the second to obtain the exclusive access to the ball object, this result is returned.

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.