It can help system performance to delay certain conditional tasks that depend on time-consuming initialization routines or other factors. After all, it is not efficient to enter a loop and check 10,000 times if a required component is finally ready for use. A better approach is to put the worker thread to sleep for an appropriate amount of time, such as 10 milliseconds, check the state of the dependencies after that time, and go back to sleep for another 10 milliseconds or continue processing when conditions permit. Use the Sleep function from within the thread itself to suspend and resume a thread. You can also use the SuspendThread and ResumeThread functions to control a thread through another thread.

The Sleep function accepts a numeric value that specifies the sleep interval in milliseconds. It is important to remember that the actual sleep interval will likely exceed this value. The Sleep function relinquishes the remainder of the current thread's quantum and the scheduler will not give this thread another time slice until the specified interval has passed and there are no other threads with higher priority. For example, the function call sleep(0) does not imply a sleep interval of zero milliseconds. Instead, sleep(0) relinquishes the remainder of the current quantum to other threads. The current thread will only continue to run if the scheduler has no other threads with the same or higher priority on the thread list.

Similar to the sleep(0) call, the SleepTillTick function relinquishes the remainder of the current thread's quantum and suspends the thread until the next system tick. This is useful if you want to synchronize a task on a system tick basis.

The WaitForSingleObject or WaitForMultipleObjects functions suspend a thread until another thread or a synchronization object is signaled. For example, a thread can wait for another thread to exit without having to enter a loop with repeated Sleep and GetExitCodeThread calls if the WaitForSingleObject function is enabled instead. This approach results in a better use of resources and improves code readability. It is possible to pass a timeout value in milliseconds to the WaitForSingleObject or WaitForMultipleObjects functions.

Thread Management Sample Code

The following code snippet illustrates how to create a thread in suspended mode, specify a thread function and parameters, change the thread priority, resume the thread, and wait for the thread to finish its processing and exit. In the last step, the following code snippet demonstrates how to check the error code returned from the thread function.

// Structure used to pass parameters to the thread.

typedef struct {

 BOOL bStop;

} THREAD_PARAM_T

// Thread function

DWORD WINAPI ThreadProc(LPVOID lpParameter) {

 // Perform thread actions...

 // Exit the thread.

 return ERROR_SUCCESS;

}

BOOL bRet = FALSE;

THREAD_PARAM_T threadParams;

threadParams.bStop = FALSE;

DWORD dwExitCodeValue = 0;

// Create the thread in suspended mode.

HANDLE hThread = CreateThread(NULL, 0, ThreadProc,

 (LPVOID) &threadParams, CREATE_SUSPENDED, NULL);

if (hThread == NULL) {

 // Manage the error...

} else {

 // Change the Thread priority.

 CeSetThreadPriority(hThread, 200);

 // Resume the thread, the new thread will run now.

 ResumeThread(hThread);

 // Perform parallel actions with the current thread...

 // Wait until the new thread exits.

 WaitForSingleObject(hThread, INFINITE);

 // Get the thread exit code

 // to identify the reason for the thread exiting

 // and potentially detect errors

 // if the return value is an error code value.

 bRet = GetExitCodeThread(hThread, &dwExitCodeValue);

 if (bRet && (ERROR_SUCCESS == dwExitCodeValue)) {

  // Thread exited without errors.

 } else {

  // Thread exited with an error.

 }

 // Don't forget to close the thread handle

 CloseHandle(hThread);

}

Thread Synchronization

The real art of multithreaded programming lies in avoiding deadlocks, protecting access to resources, and ensuring thread synchronization. Windows Embedded CE provides several kernel objects to synchronize resource access for threads in drivers or applications, such as critical sections, mutexes, semaphores, events, and interlocks functions. Yet, the choice of the object depends on the task that you want to accomplish.

Critical Sections

Critical sections are objects that synchronize threads and guard access to resources within a single process. A critical section cannot be shared between processes. To access a resource protected by a critical

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату