Understanding the Thread.Sleep function

We may often use the Thread.Sleep function to suspend the thread for a period of time. So do you have a correct understanding of the usage of this function? Consider the following two questions:

Suppose now is 2008-4-7 12:00:00.000, if I call Thread.Sleep(1000), at 2008-4-7 12:00:01.000, this thread will not will be awakened?
Someone's code used a seemingly inexplicable phrase: Thread.Sleep(0). Since it is Sleep 0 milliseconds, is there any difference between him and removing this code?
Let's review the operating system principles first.

In the operating system, there are many strategies for CPU competition. Unix systems use the time slice algorithm, while Windows is preemptive.

In the time slice algorithm, all processes are arranged in a queue. The operating system, in their order, assigns each process a period of time that the process is allowed to run. If the process is still running at the end of the time slice, the CPU will be taken away and assigned to another process. If the process blocks or ends before the time slice ends, the CPU switches immediately. All the scheduler has to do is maintain a list of ready processes, and when a process has used up its time slice, it is moved to the end of the queue.

The so-called preemptive operating system means that if a process gets CPU time, it will completely occupy the CPU unless it gives up using the CPU itself. Therefore, it can be seen that in a preemptive operating system, the operating system assumes that all processes are "good character" and will actively quit the CPU.

In a preemptive operating system, assuming there are several processes, the operating system will calculate a total priority for them according to their priority and starvation time (how long has the CPU not been used). The operating system will give the CPU to the process with the highest overall priority. When the process finishes executing or suspends itself, the operating system will recalculate the total priority of all processes, and then pick the one with the highest priority to give him control over the CPU.

We describe these two algorithms with a cake-sharing scenario. Suppose there is a steady stream of cakes (a steady stream of time), a pair of knives and forks (a CPU), and 10 people waiting to eat the cake (10 processes).

If the Unix operating system is responsible for dividing the cake, then he will set the rules like this: Everyone comes up to eat for 1 minute, and it's time to change to the next one. When the last person finishes eating, start over. So, regardless of whether the 10 people have different priorities, different hunger levels, and different appetites, everyone can eat for 1 minute when they come up. Of course, if someone is not too hungry at first, or has a small appetite, and is full after 30 seconds of eating, then he can say to the operating system: I am full (hang). So the operating system will let the next person follow.

If the Windows operating system is responsible for dividing the cake, then the scene is very interesting. He will set the rules like this: I will give each of you a priority based on your priority and hunger level. The person with the highest priority can come up and eat cake - until you don't want to. After this person has finished eating, I will recalculate the priority of each person according to the priority and hunger level, and then assign it to the person with the highest priority.

In this way, this scene is interesting - maybe some people are PPMM, so have high priority, so she can often come to eat cake. Maybe the other guy is an ugly guy and goes very ws, so the priority is very low, so it takes a long time to get his turn (because as time goes on, he will get more and more hungry, so the total priority calculated will get higher and higher, so one day it will be his turn). Moreover, if a big fat man accidentally gets a knife and fork, because he has a big appetite, he may occupy the cake and eat it for a long time, causing the person next to him to swallow. . .
Moreover, there may be such a situation: the result calculated by the operating system now, the total priority of No. 5 PPMM is the highest, and it is a lot higher than others. So called No. 5 to eat cake. No. 5 ate for a while and felt less hungry, so he said "I won't eat" (hang). So the OS will recalculate everyone's priorities. Because No. 5 has just eaten, her hunger level has become smaller, so the overall priority has become smaller; while the other people have waited for a while, and the hunger level has become larger, so the overall priority has also become larger. However, it is still possible that No. 5 has a higher priority than the others at this time, but now it is only a little higher than the others - but she is still the highest overall priority. So the operating system will say: No. 5 mm comes up to eat cake... (No. 5 mm is depressed, this is not just eaten... People want to lose weight... Who told you to look so beautiful and get such a high priority) .

So, what does the Thread.Sleep function do? It is also described with the scene of dividing the cake just now. In the above scene, after eating the cake once, MM No. 5 feels that she is already 8 points full. She feels that she does not want to eat cake again in the next half an hour, then she will tell the operating system: Don't ask me to come up for cake for the next half hour. In this way, when the operating system recalculates the total priority of everyone in the next half hour, it will ignore the 5th mm. The Sleep function does just that, telling the OS "I won't compete for the CPU for a few milliseconds in the future".

After reading the role of Thread.Sleep, let's think about the two questions at the beginning of the article.

For the first question, the answer is: not necessarily. Because you're just telling the OS: I don't want to compete for CPUs in the next 1000ms. Then after 1000 milliseconds have passed, maybe another thread is using the CPU at this time, then the operating system will not reallocate the CPU until the thread is suspended or terminated; moreover, even if it happens to be the operating system's turn to allocate the CPU at this time , then the current thread is not necessarily the one with the highest total priority, and the CPU may still be preempted by other threads.

Similarly, Thread has a Resume function, which is used to wake up a suspended thread. As said above, this function just "tells the operating system that I will compete for the CPU from now on", and the call to this function does not immediately cause the thread to gain control of the CPU.

For the second question, the answer is: yes, and the difference is obvious. Suppose we have another PPMM No. 7 in the cake-sharing scene just now, and her priority is also very, very high (because she is very, very beautiful), so the operating system will always call her to eat cake. Moreover, No. 7 also likes to eat cake very much, and the appetite is also very large. However, No. 7 has a good personality, she is very kind, and she will think: If there is someone who needs cake more than me now, then I will let him. So she can say to the OS every few bites: Let's recalculate the total priority for everyone. However, the operating system does not accept this suggestion - because the operating system does not provide this interface. So No. 7 mm changed the word: "Don't ask me to come up to eat cake in the next 0 milliseconds". This command is accepted by the operating system, so the operating system will recalculate everyone's total priority at this time - note that this time it is calculated together with the number 7, because "0 milliseconds have passed". So if there is no one who needs cake more than No. 7, then No. 7 will be called up to eat cake next time.

Therefore, the role of Thread.Sleep(0) is to "trigger the operating system to immediately restart the CPU competition". The result of the competition may be that the current thread still gains control of the CPU, or another thread may gain control of the CPU. This is also why we often write a Thread.Sleep(0) in the big loop, because this gives other threads such as the Paint thread the power to gain control of the CPU, so that the interface will not hang there.

In the end, although it is mentioned above that "unless it gives up using the CPU, it will completely occupy the CPU", but this behavior is still restricted - the operating system will monitor your occupation of the CPU, and if it finds that a thread is long Time occupying the CPU will force the thread to suspend, so in practice there will be no situation where "a thread keeps occupying the CPU". As for our large loop causing the program to feign death, it is not because this thread has been occupying the CPU. In fact, the operating system has already competed for CPU many times during this period, but other threads exited immediately after gaining control of the CPU, so it was the thread's turn to continue executing the loop, so it started again. It took a long time to be forced to suspend by the operating system. . . Therefore, it is reflected on the interface, and it looks as if this thread has been occupying the CPU.

At the end, let me explain again. The threads and processes in the text are a bit confusing. In fact, at the Windows principle level, CPU competition is at the thread level. In this article, the process and thread here are regarded as the same thing.

Original link: http://www.cnblogs.com/ILove/archive/2008/04/07/1140419.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326143139&siteId=291194637