Windows CE process, thread and Memory Management (2)

Source: Internet
Author: User
Ii. Synchronization

In most cases, threads must communicate and coordinate with each other to complete the task. For example, when multiple threads access the same resource together, you must ensure that a thread is reading the data of this resource, and other threads cannot modify it. In this case, threads need to communicate with each other to understand the behavior of the other party. Before a thread is ready to execute the next task, it must wait for the termination of the other thread to run, which also needs to communicate with each other. In the actual development process, there are many cases of synchronization between threads. Windows CE. NET provides many synchronization mechanisms. Mastering these mechanisms and using them properly will make the synchronization between threads more reasonable and efficient. The communication mechanism between processes is in the nextArticle.
Windows CE. Net has two operating modes: user mode and kernel mode. And allows an application to run in user mode.ProgramSwitch to kernel mode at any time or back. Some thread synchronization solutions run in user mode, and some run in kernel mode. In Windows core programming, switching from user mode to kernel mode requires at least 1000 CPU cycles. I have checked the source code of the API function setkmode in CE. This function is used to switch between two modes. To change the mode, you only need to modify some labels. It is difficult to determine the number of CPU cycles required. However, at least it is certain that switching back and forth takes some time. Therefore, the synchronization solution running in user mode should be prioritized in selecting the synchronization mechanism.

1. Mutual lock function
The interlock function runs in user mode. It ensures that when a thread accesses a variable, other threads cannot access this variable to ensure the uniqueness of the variable value. This access method is called atomic access. The functions and functions of the mutual lock function are listed as follows:

Function Parameters and functions
Interlockedincrement The parameter is of the plong type. This function adds 1 to a long variable.
Interlockeddecrement The parameter is of the plong type. This function minus 1 for a long variable
Interlockedexchangeadd Parameter 1 is of the plong type, and parameter 2 is of the long type. This function assigns parameter 2 to the value indicated by parameter 1.
Interlockedexchange Parameter 1 is of the plong type, and parameter 2 is of the long type. This function assigns the value of parameter 2 to the value pointed to by parameter 1.
Interlockedexchangepointer The parameter is of the pvoid * type, and parameter 2 is of the pvoid type. This function is the same as above. For more information, see help.
Interlockedcompareexchange Parameter 1 is of the plong type, parameter 2 is of the long type, and parameter 3 is of the long type. This function compares the value that parameter 1 points to with parameter 3. If it is the same, the value of parameter 2 is assigned to the value that parameter 1 points. Not the same
Interlockedcompareexchangepointer Parameter 1 is of the pvoid * type, parameter 2 is of the pvoid type, and parameter 3 is of the pvoid type. This function is the same as above. For more information, see help.

2. Critical Section
Objects in the critical section run in user mode. It ensures that all accessed resources in the critical section are not accessed by other threads until the current thread finishes executing the critical section.Code. Besides APIs, MFC also encapsulates functions in the critical section. Functions related to the critical section:

 
Void initializecriticalsection (lpcritical_section); void entercriticalsection (lpcritical_section); void partition (lpcritical_section); void deletecriticalsection (lpcritical_section );

Example:

 
Void criticalsectionexample (void) {critical_section csmycriticalsection; initializecriticalsection (& variable); // initialize the critical variable _ Try {entercriticalsection (& variable ); /// start the protection mechanism // write code here }__ finally // handle exceptions. Execute this code {leavecriticalsection (& csmycriticalsection) regardless of whether an exception occurs ); /// revoking the protection mechanism }}

The use of the MFC class is simpler:

 
Ccriticalsection Cs; CS. Lock (); // write the code CS. Unlock ();

Avoid deadlocks when using the critical section. When there are two threads, each thread has a critical section, and the resources protected by the critical section are the same, you need to consider more when writing code.

3. event object
The event object runs in kernel mode. Different from the user mode, in kernel mode, threads use the wait function to wait for the required events and signals. The waiting process is completed by the operating system kernel, while the thread is sleep, after receiving the signal, the kernel resumes the running of the thread. The advantage of kernel mode is that the thread does not waste CPU time while waiting, but it takes some time to switch from user mode to kernel mode, and it also needs to be switched back. Before explaining the event object, you should first talk about the wait function. There are four waiting functions. The specific parameters and functions are shown in the following table:

Function Parameters and functions
Waitforsingleobject Parameter 1 is handle type, and parameter 2 is DWORD type. This function waits for the event identified by parameter 1. The wait time is the value of parameter 2, in ms. If no timeout occurs, when the event becomes in a signal state, the thread wakes up and continues to run.
Waitformultipleobjects Parameter 1 is of the DWORD type, parameter 2 is of the handle * type, parameter 3 is of the bool type, and parameter 4 is of the DWORD type. This function waits for all the events in the array to which parameter 2 points. If no timeout occurs, when parameter 3 is false, the function returns the index of an event as long as an event is in a signal state. When parameter 3 is set to true, it is returned only when all events are in the signal state.
Msgwaitformultipleobjects Parameter 1 is of the DWORD type, parameter 2 is of the lphandle type, parameter 3 is of the bool type, parameter 4 is of the DWORD type, and parameter 5 is of the DWORD type. This function is similar to the waitformultipleobjects function, but has an additional wake-up mask. The wake-up mask is related to messages. This function not only waits for events, but also for specific messages. In fact, this function is specifically defined for waiting for messages.
Msgwaitformultipleobjectsex Parameter 1 is DWORD type, parameter 2 is lphandle type, parameter 3 is DWORD type, parameter 4 is DWORD type, and parameter 5 is DWORD type. This function is an extension of the msgwaitformultipleobjects function. Remove parameter 3 of the original function and add parameter 5 as the flag. The flag has two values: 0 or mwmo_inputavailable.

If a thread needs to execute a large number of tasks and respond to users' key messages, these two functions are very useful for waiting for messages.

Event-related functions include:

 
Handle createevent (handle events, bool bmanualreset, bool binitialstate, lptstr lpname); bool setevent (handle hevent); bool pulseevent (handle hevent); bool resetevent (handle hevent ); handle openevent (DWORD dwdesiredaccess, bool binherithandle, lpctstr lpname );

Event objects are the most common kernel-mode Synchronization Methods. It contains one count and two bool variables. One of the bool variables specifies whether the event object is automatically reset or manually reset. Another bool variable specifies whether the current event object is in the signal or no signal state.
The createevent function creates an event object. Parameter 1 must be null. Parameter 2 specifies whether to manually reset the status of the event object. If this parameter is set to false, the event object is automatically set to stateless after the function receives a signal and returns the result. At this time, other threads waiting for this event object will not be awakened, because the event object has been set to non-signal state. If parameter 2 is set to true, when the wait function receives a signal and returns the result, the event object is not automatically placed in the non-signal state, and other threads waiting for this event object can be awakened. You can use the resetevent function to manually set the event object to a non-signal state. On the contrary, the setevent function sets the event object to a signal state. The pulseevent function sets the event object to a signal state and immediately sets it to a signal-free State. In actual development, this function is rarely used. The openevent function opens the created event object, which is generally used for Thread Synchronization in different processes. When createevent is called to create an event object, a name is passed to parameter 4, so that threads in other processes can call the openevent function and specify the name of the event object to access this event object.

4. mutex object
The mutex runs in kernel mode. Its behavior is very similar to that in the critical section. When a thread accesses a shared resource, it ensures that other threads cannot access this resource. The difference is that mutex objects run in kernel mode, which is slower than the critical section in time. Because the kernel object is global, different processes can access it. In this way, mutex objects can be used to allow threads in different processes to access a shared resource. The critical section can only be valid within one process.

Mutually Exclusive functions include:

 
Handle createmutex (lpsecurity_attributes lpmutexattributes, bool binitialowner, lpctstr lpname); bool releasemutex (handle hmutex );

A mutex contains a reference count, a thread ID, and a recursive count. The reference count is contained in all kernel objects. Thread ID indicates which thread is using mutex resources. When the ID is 0, the mutex object sends a signal. Recursive counting is used for a thread to wait for the same mutex object multiple times. The createmutex function creates a mutex object. Parameter 1 must be set to null. If parameter 2 is set to false, the current thread does not possess mutex resources, the thread ID and recursive count of the mutex are both set to 0, and the mutex is in a signal state. If this parameter is set to true, the current thread occupies the mutex resource. The thread ID of the mutex object is set to the current thread ID, the recursive count is set to 1, and the mutex object is in the non-signal state. When a wait function is called, wait for the function to check whether the thread ID of the mutex object is 0. If it is 0, no thread is currently accessing the mutex resource, and the kernel will wake up the thread, add the recursive count of the mutex object to 1. After a thread is awakened, you must call the releasemutex function to reduce the recursive count of mutex objects by 1. If a thread calls the wait function multiple times, the releasemutex function must be called the same number of times. Unlike other Windows systems, functions related to mutex do not have the openmutex function. To access the same mutex object in different processes, call the createmutex function. The parameter passes the name of the mutex object and returns the handle of the mutex object.

5. Beacon object
A beacon object, also called a traffic signal, is used to limit the number of resource accesses. It contains a reference count, the number of currently available resources, and the maximum number of available resources. If the number of available resources is greater than 0, the beacon object is in a signal state. When the number of available resources is equal to 0, the beacon object is in the non-signal state.

Functions related to the credit object:

 
Handle createsemaphore (commandid, long linitialcount, long lmaximumcount, lpctstr lpname); bool releasesemaphore (handle hsemaphore, long lreleasecount, lplong lppreviouscount );

Parameter 1 of the createsemaphore function is null, parameter 2 is the initial value of the currently available resources, parameter 3 is the maximum number of available resources, and parameter 4 is the name. When the value of parameter 2 is equal to 0, the beacon object is in the non-signal state, then the kernel puts the thread that calls the waiting function in the sleep state, if the value of parameter 2 is greater than 0, the beacon object is in the signal State. At this time, the kernel puts the thread that calls the waiting function in the running state, and reduces the number of currently available resources of the beacon object by 1. Parameter 1 of the releasesemaphore function is the handle of the tag object, parameter 2 is the number of resources to be released, and parameter 3 returns the original number of available resources, call this function to add the value of parameter 2 to the number of currently available resources. After a thread has accessed available resources, call the releasesemaphore function to increase the number of available resources. To access the same beacon object in different processes, call the createsemaphore function and pass the name of the beacon object to obtain the handle of the beacon object created in other processes. There is no opensemaphore function in CE. In addition, I want to explain that the number of currently available resources of the beacon object is reduced by 1 by default, but the thread may use multiple resources at a time, which may cause problems. To avoid problems, we should follow the principle that one thread only uses one resource.

6. Message Queue
Windows CE. Net allows an application or driver to create its own message queue. Message Queue can be used as a tool for data transmission between threads or for synchronization between threads. It requires a small amount of memory and is generally only used for point-to-point communication.

Functions related to message queue:

Handle winapi handle (maid); bool winapi handle (handle hmsgq); bool handle (handle hmsgq, lpmsgqueueinfo lpinfo); handle winapi handle (handle, handle hmsgq, lpmsgqueueoptions lpoptions); bool sort (handle sort, lpvoid lpbuffer, DWORD cbbuffersize, lpdword sort, DWORD dwtimeout, DWORD * pdwflags); bool winapi sort (handle sort, lpvoid lpbuffer, DWORD cbdatasize, DWORD dwtimeout, DWORD dwflags );

Use the createmsgqueue function to create a message queue and pass a msgqueueoptions structure pointer. Set a flag in this structure (allow the queue buffer to dynamically change the size, allow direct read or write operations, regardless of whether there have been write or read Operations) maximum number of messages allowed by the queue, queue attributes (read-only or write-only ). Use the writemsgqueue function to write a message to the message queue. The buffer that passes a message queue, the size of the message data, the timeout value and flag of the write buffer. Use the readmsgqueue function to read a message from the message queue. Use the closemsgqueue function to disable the Message Queue buffer. Use the openmsgqueue function to open the Message Queue created in other processes. You can also use the wait function to wait for changes in the message queue. The thread that calls the wait function is wakened when a message queue is from no message to no message, or when a message is full to no message. I have never tried MNS. There are several simple examples on msdn.

Related Article

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.