官术网_书友最值得收藏!

Introduction

As we saw in Chapter 1, Threading Basics, it is problematic to use a shared object simultaneously from several threads. It is very important to synchronize those threads so that they perform operations on that shared object in a proper sequence. In a multithreaded counter recipe, we met a problem called the race condition. It happened because the execution of those multiple threads were not synchronized properly. When one thread performs the increment and decrement operations, the other threads must wait for their turn. This general problem is often referred to as thread synchronization.

There are several ways to achieve thread synchronization. First, if there is no shared object, there is no need for synchronization at all. Surprisingly, it is very often that we can get rid of complex synchronization constructs by just redesigning your program and removing a shared state. If it's possible, just avoid using a single object from several threads.

If we must have a shared state, the second approach is to use only atomic operations. This means that an operation takes a single quantum of time and completes at once, so no other thread can perform another operation until the first operation is complete. Therefore, there is no need to make other threads wait for this operation to complete and there is no need to use locks; this in turn excludes the situation of a deadlock.

If this is not possible and the program's logic is more complicated, then we have to use different constructs to coordinate threads. One group of those constructs puts a waiting thread into a blocked state. In a blocked state, a thread uses as little CPU time as possible. However, this means that it will include at least one so-called context switch—the thread scheduler of an operating system—that will save the waiting thread's state, and switch to another thread, restoring its state by turn. This takes a considerable amount of resources; however, if the thread is going to be suspended for a long time, it is good. These kinds of constructs are also called kernel-mode constructs because only the kernel of an operating system is able to stop a thread from using CPU time.

In case we have to wait for a short period of time, it is better to simply wait than switch the thread to a blocked state. This will save us the context switch at the cost of some CPU time wasted while the thread is waiting. Such constructs are referred to as user-mode constructs. They are very lightweight and fast, but they waste a lot of CPU time in case a thread has to wait for long.

To use the best of both the worlds, there are hybrid constructs; these try to use the user-mode waiting first, and then if a thread waits long enough, it switches to a blocked state, saving CPU resources.

In this chapter, we will look through the aspects of thread synchronization. We will cover how to perform atomic operations and how to use the existing synchronization constructs included in the .NET framework.

主站蜘蛛池模板: 东阿县| 玉山县| 金昌市| 梁河县| 甘谷县| 遵义县| 泾阳县| 瑞丽市| 游戏| 开鲁县| 平舆县| 郓城县| 兴化市| 西畴县| 阿拉尔市| 大姚县| 白城市| 开江县| 镇江市| 延川县| 南昌市| 随州市| 迁西县| 嵊泗县| 弥渡县| 友谊县| 同心县| 武威市| 襄垣县| 浮梁县| 桂林市| 苗栗市| 宿迁市| 衢州市| 九龙坡区| 扎兰屯市| 稻城县| 五峰| 渝北区| 康保县| 沁阳市|