Chapter 7: thread scheduling, priority, and relevance

Source: Internet
Author: User
Tags sleep function

1. context switching: around 20 ms (you can use the second parameter of the getsystemtimeadjustment function for details). Windows displays all existing thread kernel objects. only some of these objects are considered to be schedulable. windows selects one of the schedulable thread kernel objects and loads the value last saved in the thread context into the CPU register.
Note: we cannot guarantee that the thread is always running, the thread will obtain the entire processor, and the system will not allow other threads to run.

2. there is a thread suspension count in the thread kernel object. When createthread or getprocess is called, the system will create the thread Kernel Object and initialize the suspension count to 1. in this way, the CPU will not be scheduled for this thread. this is because we need to wait until the thread is fully initialized. after the initialization is successful, the system checks whether the createthread and CreateProcess have the create_suincluded flag. if yes, the function will return and put the new thread in the suspended state. Otherwise, the function will reduce the suspended count to 0 and make it a schedulable state, unless it waits for a certain period of time (such as keyboard input, other locked variables or resources ).

In addition, a thread can be suspended for multiple times. Assume that a thread has been suspended for n times. If you want it to resume n times before continuing to allocate the CPU, you must call the resumethread function, at this time, N should be less than 127 ).

Note that if the resumethread and suspendthread functions are successfully called, the suspension count before the thread is returned. in kernel mode, suspendthread is asynchronous, but it cannot run in user mode before the thread recovers. (that is, it is only asynchronous in kernel mode)

Windows does not have the concept of suspending or resuming processes. because the system never schedules CPU time for the process. in a special case, when the debugger processes the debugging event returned by waitfordebugevent, Windows freezes all threads in the debugging process until the debugger calls continuedebugevent.

Void suspendprocess (DWORD dwprocessid, bool fsuspend)

{

Handle hsnapshot = createconlhelp32snapshot (th32cs_snapthread, dwprocessid); // obtain the handle marked by dwprocessid

If (hsnapshot)

{

Threadentry32 TE = {sizeof (TE )};

Bool Fok = thread32first (hsnapshot, & Te); // find the first thread of the process for (; Fok = thread32next (hsnapshot, & Te ))

{

If (TE. th32ownerprocessid = dwprocessid)

{

Handle hthread = openthread (thread_suspend_resume, false, te. th32threadid );

// Match the kernel object associated with the thread ID. Note that the kernel count increases by 1 at this time.

If (hthread! = NULL)

{

If (fsuspend)

{

Suspendthread (hthread );

}

Else

{

Resumethread (hthread );

}

}

Closehandle (hthread );

}

}

Closehandle (hsnapshot );

}

}

When using the suspendprocess function, the process marked by the dwprocessid parameter is not fixed (whether the process has been canceled, or whether a new thread has been generated and a new thread has been occupied, so we 'd better use it less to suspend the process.

3. A Sleep thread can call the sleep function:

Void sleep (DWORD dwmilliseconds) // causes the thread to suspend dwmilliseconds for its own time
Note the following when calling a dry function:

◆ Calling the sleep function will allow the thread to voluntarily discard its own remaining time slice

◆ The system sets that the thread cannot be scheduled for only "Approximate" milliseconds, because the windows non-Real-Time System

◆ Infinite can be passed in. At this time, the system is told never to schedule this process.

◆ 0 can be passed in. At this time, the main thread tells the system that it has abandoned the remaining part of the time slice. It forces the system to call other threads. However, the system may schedule the thread that has just scheduled sleep.

4. Switch thread:

Bool switchtothread ();

Note: When this function is called, The system checks whether there are hunger threads in urgent need of CPU time. if not, the function returns immediately. if yes, the function changes the scheduling thread (the priority may be lower than the priority of the main thread of the function ). A hunger thread can run a time amount, and then the system scheduler returns to normal.

The call to switchtothread is similar to the call to sleep. You can pass in 0. The difference is that switchtothread allows low-priority threads to be executed. The sleep will be rescheduled immediately, even if the low-priority thread is still in the hunger state.

5. If we want to get the time required for a complex algorithm, we can call getthreadtimes.

Bool getthreadtimes (

Handle hthread,

Pfiletime pftcreationtime,

Pfiletime pftexittime,

Pfiletime pftkerneltime,

Pfiletime pftusertime );

The four return values are defined as follows:

Time Value

Description

Creation Time

An absolute value used to indicate the thread creation time. In the unit of NS, the creation time is calculated starting from the midnight on January 1, 1606, the green time.

Exit Time

In the unit of 100ns, the creation time is calculated from the midnight on July 15, January 1, 1606, which is the absolute value of the thread exit time. If the thread is still running, the exit time is meaningless.

Kernel Time

Indicates the absolute value of the time used by the operating system code in the kernel mode of thread execution, expressed in NS.

User time

Used to indicate the absolute time value used by the thread to execute the application code, expressed in NS

The following function converts the time represented by pfiletime to the actual time used:

_ Int64 filetimetoquadword (pfiletime PFT)

{

Return (int64shllmod32 (PFT-> dwhighdatetime, 32) | PFT-> dwlowdatetime );

}

There is also a get process running time:

Bool getprocesstimes (

Handle hthread,

Pfiletime pftcreationtime,

Pfiletime pftexittime,

Pfiletime pftkerneltime,

Pfiletime pftusertime );

The obtained time is the total time of all threads.

Features of Vista:

The method for allocating CPU time to threads has changed. The system no longer depends on the interval clock timer (about 10 ~ The 64-bit timestamp timer (TSC) of the processor is used to calculate the number of clock cycles since the machine started. you can use readtimestampcounter to obtain the value of TSC. this macro is defined as the internal function _ rdtsc provided by the C ++ compiler.

The querythreadcycletime and queryprocesscycletime functions return the number of clock cycles used by all threads of a given thread or process.

To use high-precision performance analysis, you must use the following two functions:

Bool queryperformancefrequency (large_integer * plifrequency );

Bool queryperformancecounter (large_integer * plicount );

These functions assume that the thread being executed will not be preemptible.

You can use a class encapsulated by the author on <windows core programming>.

6. The context structure records the state of the thread, so that the thread can continue from the last stop when it gets the CPU to run.

Windows allows us to view the internal structure members of the thread kernel object. You can use getthreadcontext:

Bool getthreadcontext (

Handle hthread,

Pcontext );

Description of function call: First assign a context structure, initialize some flag (contextflags member) to obtain those registers, and then use pcontext as the return value.

Note that when calling this function, you should first call suspendthread; otherwise, the system may obtain the scheduling thread; in this way, the context of the thread is inconsistent with the information obtained.

The context is divided into user mode and kernel mode. getthreadcontext can only return user mode.

Relationship between contextflags and values:

Contextflags Value

Meaning

Context_control

CPU control register

Context_integer

Integer register

Context_segments

Segment register

You can also use setthreadcontext to set the context. However, it is generally not recommended to use it. This can easily cause access violations.

7. A thread with a higher priority always preempys a thread with a lower priority, regardless of whether the thread with a lower priority is being executed. in addition, when the system starts, the system will create a special thread named page clearing thread. this thread has a priority of 0 and is the only thread with a priority of 0 in the system. the page clearing thread clears all idle pages in the system memory when no other process needs to be executed.
■ Process priority set

Priority

Description

Real-time (Real-Time)

The threads in this process must immediately respond to the event and execute real-time tasks. The threads in this process will also seize the CPU time of the OS components. Therefore, be extremely careful.

High)

The thread in this process must immediately respond to the event and execute real-time tasks. The task manager runs at this level, so you can end a process that is empty through it.

Above normal (higher than standard)

The threads in this process run between the normal and high priority.

Normal (standard)

Threads in this process do not need special Scheduling

Below normal (lower than standard)

The threads in this process run between normal and idle.

Idle (low)

Threads in this process run when the system is idle, screen saver, background programs and statistical data collection software usually use this process.

The process cannot run in the real-time priority class. unless the user has the Increase Scheduling Priority (higher plan priority) privilege. by default, Users affiliated with administrators or advanced user groups have this permission.

■ Relative thread priority

Relative thread priority

Description

Time-critical

For the real-time priority class, the thread runs on 31, and all other priorities run on 15

Highest

The thread runs at two levels above normal

Above normal

The thread runs at a level higher than normal.

Normal

The thread runs at the normal level.

Below normal

The thread runs at a level lower than normal.

Lowest

The thread runs at two levels below normal.

Idle

For the real-time priority class, the thread runs at 16; all other priorities run at 1.

A thread belongs to a certain priority class. You can specify the relative thread priority of a thread in a process. remember: The thread priority is relative to the process priority. if the process priority is changed. the relative priority of the thread remains unchanged, but the priority value changes. if the application is running in user mode, you cannot obtain the priority: 17 ~ ~ 30. If it is in kernel mode, there is no restriction. The priority value of a thread in the real-time priority class cannot be lower than 16, and the fly real-time cannot be higher than 15.

Generally, threads with a higher priority should not be scheduled during programming. the status with low priority is schedulable. (This allows the system to quickly obtain the CPU time when executing a high-priority thread)

8. ■ if you want to assign a priority to the process, you can pass the following priority identifier to the fdwcreate parameter when calling getprocess.

Priority

Identifier

Real-time

Realtime_priority_class

High

High_priority_class

Above normal

Above_normal_priority_class

Normal

Normal_priority_class

Below normal

Below_normal1_priority_class

Idle

Idle_priority_class

You can use the following two functions to set and obtain the priority of a process:

Bool setpriorityclass (

Hanle hprocess,

DWORD fdwpriority)

DWORD getpriorityclass

Hanlde hprocess)

When you call a program through the command line interface, the initial priority of the program is normal. However, you can specify a priority by using the start command. For example, c: \> Start/low process.exe

Likewise, the relative priority identifier of a thread

Relative thread priority

Symbol constant

Time-critical

Thread_priority_time_critical

Highest

Thread_priority_time_highest

Above normal

Thread_priority_time1_above_normal

Normal

Thread_priority_time_normal

Below normal

Thread_priority_time_below_normal

Lowest

Thread_priority_time_lowest

Idle

Thread_priority_time_idle

Correspondingly, you can use the following function to obtain the relative priority of a thread:

Int getthreadpriority (handle hthread );

Note: Windows does not provide a function to return the thread priority. Microsoft intentionally omitted this function. remember that Microsoft reserves the right to change the scheduling algorithm at any time. the application we designed should not understand the details of the scheduling algorithm. if we always use the process priority class and the relative thread priority class, our applications can run well in the current and future versions of the OS.

■ The system determines the thread priority value (basic priority value) by adding the relative priority of the thread and the priority of the process to which the thread belongs ), however, the system will increase its basic priority (for example, Io events) due to a special event ).

The priority of the system improvement will be smaller and smaller as the process runs, but it will not be lower than the basic priority of the thread in principle. It can only be increased by 1 ~ 15 threads (this range is also called the dynamic priority range), and will not exceed this range (more than 15 is also called the real-time range). The system cannot dynamically improve the threads in the real-time range.

Of course, you can also disable/allow the system to dynamically increase the priority of a thread:

Bool setprocesspriorityboot (

Handle hprocess,

Bool bdisablepriorityboot );

Bool setthreadpriorityboot (

Handle hthread,

Bool hdisablepriorityboot );

Corresponding permission for obtaining priority:

Bool getprocesspriorityboot (

Handle hprocess,

Pbool bdisablepriorityboot );

Bool getthreadpriorityboot (

Hnalde hthread,

Pbool bdisablepriorityboot );

Another way for the system to increase its priority is thread hunger.

If you need to use a process window, this process becomes a foreground process. at this time, the system will fine-tune the scheduling algorithm so that the process has more time slices. note that this fine-tuning is performed only when the process has a normal priority. in Vista, you can set whether to perform fine-tuning.

■ Setting the thread priority will affect how the system allocates CPU resources to the thread. However, in addition to the thread priority, there are also I/O requests to read and write data to disk files.

Starting from Vista, the thread can set the priority during I/O requests. call setthreadpriority and input thread_mode_background_begin to inform windows that the thread should send low-priority IO requests (which also reduces the CPU scheduling priority of the thread ). alternatively, input thread_mode_background_end to allow the thread to perform normal priority IO requests (and normal CPU scheduling priority ).

If you want all threads in the process to perform low-priority IO requests and Low-CPU scheduling, we can schedule setpriorityclass and pass in the process_mode_background_begin flag. The opposite operation can pass in the process_mode_background_end flag.

In addition, to make the system more fine-grained, the normal priority thread can also execute background priority Io for a file:

Setfileinformationbyhandle sets the priority to overwrite the priority or thread of the process (that is, the priority set through the above two functions ).

9. concept:

Soft Association: if other factors are the same, the system will enable the thread to run on the last running processor. enabling threads to always run on the same processor helps to reuse data that is still in the high-speed buffer of the processor.

Hard swap: controls which CPUs are allowed to run specific threads.

Use getsysteminfo to query the number of CPUs on the machine.

Restrict certain threads to run only on a subset of available CPUs:

Bool setprocessaffinitymask (

Handle hprocess,

Dword_ptr dwprocessaffinitymask); // bit mask.

Note: Sub-processes will inherit process associativity.

Correspondingly, obtain the associativity mask of the process:

Bool getprocessaffinitymask (

Handle hprocess,

Pdword_ptr pdwprocessaffinitymask, // returns the correlated mask of the process.

Pdword_ptr pdwsystemaffinitymask) // returns the System Correlation mask.

The so-called correlated mask indicates which CPU in the system can be used for these threads. The correlated mask of the process is always a real subset of the system-related downlink mask.

You can use the following functions to obtain the correlated mask:

Dword_ptr setthreadaffinitymask (

Handle hthread,

Dword_ptr dwthreadaffinifymask); // The number of CPUs that the thread can run on. It must be a real subset of the Process associativity mask.

Returned value: the associated mask before the thread.

If you perform the preceding operations, the resource allocation may be extremely unreasonable. Therefore, Windows provides another method to set an ideal CPU for the thread.

DWORD setthreadidealprocessor (

Handle hthread,

DWORD dwidealprocessor) // The value ranges from 0 ~ 31/63. If the maximum_processors statement is passed, // The thread does not have an ideal CPU.

Returned value: the ideal CPU is returned. Otherwise, maximum_processors 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.