Multithread API’s Adam Piotrowski Grzegorz Jabłoński Lecture IV.

Slides:



Advertisements
Similar presentations
Process A process is usually defined as an instance of a running program and consists of two components: A kernel object that the operating system uses.
Advertisements

Lesson 12: Kernel-mode Thread Sync (aka: Why I love Gentoo)
Multi-core Programming Programming with Posix Threads.
Project 2 教學. Synchronization Functions in Windows HANDLE WINAPI CreateSemaphore ( __in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, __in LONG lInitialCount,
CS 140 Lecture Notes: Processes and ThreadsSlide 1 UNIX Fork/Exec Example int pid = fork(); if (pid == 0) { exec("foo"); } else { waitpid(pid, &status,
CS444/CS544 Operating Systems Classic Synchronization Problems 2/28/2007 Prof. Searleman
Critical Sections and Semaphores A critical section is code that contains access to shared resources that can accessed by multiple processes. Critical.
Computer Architecture II 1 Computer architecture II Programming: POSIX Threads OpenMP.
CS444/CS544 Operating Systems Synchronization 2/28/2006 Prof. Searleman
1 JMH Associates © 2004, All rights reserved Chapter 6 Process Management.
CS 284a, 8 October 1997 Copyright (c) , John Thornley1 CS 284a Lecture Wednesday, 8 October, 1997.
ISP – 3 rd Recitation “The joy of Windows API” Processes Threads Handles Relevant functions A simple code example.
ISP – 7 th Recitation Mid semester!!! Semaphores – reminder Events Code examples.
CS444/CS544 Operating Systems Synchronization 2/19/2007 Prof. Searleman
ISP – 5 th Recitation Mutexes Code example. Mutex Wikipedia definition: Mutual exclusion (often abbreviated to mutex) algorithms are used in concurrent.
8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability.
ISP – 4 th Recitation Times System Errors Threads Waits Code examples.
Threads CNS What is a thread?  an independent unit of execution within a process  a "lightweight process"  an independent unit of execution within.
Pthread (continue) General pthread program structure –Encapsulate parallel parts (can be almost the whole program) in functions. –Use function arguments.
Introduction to Pthreads. Pthreads Pthreads is a POSIX standard for describing a thread model, it specifies the API and the semantics of the calls. Model.
MultiThreaded Applications. What is Multithreaded Programming? Having your software appear to perform multiple tasks in parallel –Individual paths of.
Multi-core Programming Programming with Windows Threads.
2.3 InterProcess Communication (IPC)
1-1 © 2004 JMH Associates. All rights reserved. Windows Application Development Chapter 7 Windows Thread Management.
Windows thread programming
Multithreaded Programming With the Win32 API Andrew Tucker Andrew Tucker Debugger Development Lead March 13, 1998.
Multi-threaded Programming with POSIX Threads CSE331 Operating Systems Design.
Threads and Thread Control Thread Concepts Pthread Creation and Termination Pthread synchronization Threads and Signals.
Copyright ©: University of Illinois CS 241 Staff1 Synchronization and Semaphores.
CS345 Operating Systems Threads Assignment 3. Process vs. Thread process: an address space with 1 or more threads executing within that address space,
What is a thread? process: an address space with 1 or more threads executing within that address space, and the required system resources for those threads.
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Semaphore and Mutex Operations.
Programming with POSIX* Threads Intel Software College.
ITEC 502 컴퓨터 시스템 및 실습 Chapter 2-1: Process Mi-Jung Choi DPNM Lab. Dept. of CSE, POSTECH.
Multithreading GSP-420.
Programming with Windows* Threads Intel Software College.
1 Pthread Programming CIS450 Winter 2003 Professor Jinhua Guo.
POSIX Synchronization Introduction to Operating Systems: Discussion Module 5.
Windows Thread Management
Pthreads.
Practical Sockets and Threads Derek Weitzel. Windows Threads Concurrent processing Concurrent processing Windows Create Thread Windows Create Thread HANDLE.
Fall 2002 CS 325 Class Notes Page 1 Lecture 25 Today –exec() in Unix –CreateProcess in Windows Announcements.
Chapter 6 P-Threads. Names The naming convention for a method/function/operation is: – pthread_thing_operation(..) – Where thing is the object used (such.
Windows CE Overview and Scheduling Presented by Dai Kawano.
Windows CE Portable Modular Real-time Small footprint Embedded market.
Notes on Processes, Context, Context Switching The following slides contain partially quoted statements from various Wikipedia pages.
PThread Synchronization. Thread Mechanisms Birrell identifies four mechanisms commonly used in threading systems –Thread creation –Mutual exclusion (mutex)
Win32 Synchronization CS Spring Overview Kernel Synchronization - Spinlocks Executive Synchronization - Dispatcher Objects Wait Operations.
Working with Pthreads. Operations on Threads int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void * (*routine)(void*), void* arg) Creates.
Web Server Architecture Client Main Thread for(j=0;j
pThread synchronization
Case Study: Pthread Synchronization Dr. Yingwu Zhu.
Lecture Lecture 25 Review of Last Lecture DLL’s DLL’s Processes Processes Threads Threads Memory Management Memory Management.
Window Threads Chapter 7 Windows Thread Management.
Synchronization and Semaphores
CS 537 – Introduction to Operating Systems
Process Synchronization
Shared-Memory Programming with Threads
Windows Concurrency Concepts and APIs
Linux Fork/Exec Example
UNIX Fork/Exec Example
Waiting and Synchronization
Chapter 05. Multithread.
UNIX Fork/Exec Example
Windows Development Dynadata Copyright, 2014 © DynaData S.A. 1/49.
Console A presentation by Inti Vincenzo Pizzoni.
Linux Fork/Exec Example
26.
Window Application Development
POSIX Threads(pthreads)
Presentation transcript:

Multithread API’s Adam Piotrowski Grzegorz Jabłoński Lecture IV

Synchronisation Mutexes Semaphores Condition Variables 2

Mutex The mutual exclusion lock is the simplest and most primitive synchronization variable. It provides a single, absolute owner for the section of code (thus a critical section) that it brackets between the calls to pthread_mutex_lock() and pthread_mutex_unlock(). The first thread that locks the mutex gets ownership, and any subsequent attempts to lock it will fail, causing the calling thread to go to sleep. 3

Mutex initialisation NAME pthread_mutex_init, pthread_mutex_destroy - initializes mutex with attr or destroys the mutex, making it unusable in any form SYNOPSIS #include int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); 4

Mutex unlock operation NAME pthread_mutex_unlock - unlocks mutex and wakes up the first thread sleeping on it. SYNOPSIS #include int pthread_mutex_unlock(pthread_mutex_t *mutex); 5

Mutex example thread 1 add(request_t *request) { pthread_mutex_lock(&lock); request->next = requests; requests = request pthread_mutex_unlock(&lock); } thread 2 request_t *remove() { pthread_mutex_lock(&lock);...sleeping... request = requests; requests = requests->next; pthread_mutex_unlock(&lock) return(request); } 6

Mutex example 7

Semaphores A counting semaphore6 is a variable that you can increment arbitrarily high, but decrement only to zero. A sem_post() operation increments the semaphore, while a sem_wait() attempts to decrement it. If the semaphore is greater than zero, the operation succeeds; if not, then the calling thread must go to sleep until a different thread increments it. 8

Semaphores initialisation NAME sem_init, sem_destroy - initializes the semaphore to value. If pshared is non-zero, then the semaphore will be sharable among processes. This destroys the semaphore. SYNOPSIS #include int sem_init(sem_t *sem, int pshared, unsigned int value); int sem_destroy(sem_t *sem); 9

Semaphores operations NAME sem_post, sem_wait, sem_trywait - function increments the value of the semaphore or decrements the value of sem by one. If the semaphore’s value is zero, sem_wait() blocks, waiting for the semaphore to be incremented by another process or thread, while sem_trywait() will return immediately. SYNOPSIS #include int sem_post(sem_t *sem); int sem_trywait(sem_t *sem); int sem_wait(sem_t *sem); 10

Semaphores operations 11

Semaphores operations NAME sem_open, sem_close - returns a pointer to the semaphore name. All processes which call this on the same name will get the same semaphore pointer or closes the named semaphore for this process. SYNOPSIS #include sem_t *sem_open(char *name, int oflag,... ); int sem_close(sem_t *sem); 12

Semaphors example 13

Semaphors example 14 producer() { request_t *request; while(1) { request = get_request(); add(request); sem_post(&requests_length); } consumer() { request_t *request; while(1){ SEM_WAIT(&requests_length); request = remove(); process_request(request); } request_t *get_request() { request_t *request; request = (request_t *) malloc(sizeof(request_t)); request->data = read_from_net(); return(request) } void process_request(request_t *request) { process(request->data); free(request); }

Conditional Variables 15

Conditional Variable initialisation NAME pthread_cond_init, pthread_cond_destroy - initializes cond with att or destroys the condition variable, making it unusable in any form. SYNOPSIS #include int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond); 16

Conditional Variable Wait Operation NAME pthread_cond_wait, pthread_cond_timewait - atomically releases mutex and causes the calling thread to block on cond. Upon successful return, the mutex will be reacquired. SYNOPSIS #include int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); 17

Conditional Variable Signal Operation NAME pthread_cond_signal, pthread_cond_broadcast - unblocks the first thread (if any) blocked on a condition variable or unblocks all threads blocked on a condition variable. You do not know the order in which they awake. SYNOPSIS #include int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); 18

Conditional Variable Example thread 1 pthread_mutex_lock(&m); while (!my_condition) pthread_cond_wait(&c, &m);... sleeping... do_thing() pthread_mutex_unlock(&m); thread 2 pthread_mutex_lock(&m); my_condition = TRUE; pthread_mutex_unlock(&m); pthread_cond_signal(&c); 19

Conditional Variable Example 20

Conditional Variable Example void *producer(void *arg) { request_t *request; while(1) { request = get_request(); pthread_mutex_lock(&r_lock); while (length >= 10) pthread_cond_wait(&r_producer, &r_lock); add(request); length++; pthread_mutex_unlock(&r_lock); pthread_cond_signal(&r_consumer); } void *consumer(void *arg) { request_t *request; while(1) { pthread_mutex_lock(&r_lock); while (length == 0) pthread_cond_wait(&r_consumer, &r_lock); request = remove(); length--; pthread_mutex_unlock(&r_lock); pthread_cond_signal(&r_producer); process_request(request); } 21

Multithread API’s Windows OS 22

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 23

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 24 Pointer to a null-terminated string that specifies the module to execute.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 25 Pointer to a null-terminated string that specifies the command line to execute.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 26 A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 27 If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 28 Additional creation flags e.g. CREATE_NEW_CONSOLE, CREATE_SUSPENDED, DETACHED_PROCESS

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 29 A pointer to the environment block for the new process.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 30 The full path to the current directory for the process.

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 31 A pointer to a STARTUPINFO

Processes NAME CreateProcess - creates a new process and its primary thread. SYNOPSIS BOOL CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); 32 A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

Process example void _tmain( int argc, TCHAR *argv[] ) { STARTUPINFO si; PROCESS_INFORMATION pi; if( !CreateProcess( NULL, // No module name (use command line) argv[1], // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d)\n", GetLastError() ); return; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } 33

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 34

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 35 A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 36 The initial size of the stack, in bytes.

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 37 A pointer to the application-defined function to be executed by the thread and represents the starting address of the thread. DWORD ThreadProc(LPVOID lpParameter );

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 38 A pointer to a variable to be passed to the thread.

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 39 The flags that control the creation of the thread i.e. CREATE_SUSPENDED.

Threads NAME CreateThread- creates a thread to execute within the address space of the calling process. SYNOPSIS HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack, LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread ); 40 A pointer to a variable that receives the thread identifier.

Threads - Example int _tmain() { PMYDATA pData[MAX_THREADS]; DWORD dwThreadId[MAX_THREADS]; HANDLE hThread[MAX_THREADS]; int i; for( i=0; i<MAX_THREADS; i++ ) { pData[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA)); pData->val1 = i; pData->val2 = i+100; hThread[i] = CreateThread( NULL, // default security attributes 0, // use default stack size MyThread, // thread function pData, // argument to thread function 0, // use default creation flags &dwThreadId[i]); // returns the thread identifier }} WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); // Close all thread handles and free memory allocation. for(i=0; i<MAX_THREADS; i++) { CloseHandle(hThread[i]); } HeapFree(GetProcessHeap(), 0, pData[i]); return 0; } 41

What is wrong with CreateThread function ? A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread 42

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 43

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 44 Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 45 Stack size for a new thread or 0.

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 46 Start address of a routine that begins execution of a new thread.

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 47 Argument list to be passed to a new thread.

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 48 Argument list to be passed to a new thread.

_beginthreadex NAME _beginthreadex - creates a thread to execute within the address space of the calling process. SYNOPSIS uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); 49 Points to a 32-bit variable that receives the thread identifierlist to be passed to a new thread.

_beginthreadex example int main() { HANDLE hThread; unsigned threadID; printf( "Creating second thread...\n" ); hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID ); WaitForSingleObject( hThread, INFINITE ); CloseHandle( hThread ); } 50

ExitThread or return ExitThread is the preferred method of exiting a thread in C code. Return is the preferred method of exiting a thread in C++ code. 51

Synchronisation Synchronisation in user mode –Atomic access –Critical sections Synchronisation in kernel mode –Wait functions –Mutexes –Semphores 52

SYNCHRONISATION IN USER MODE 53

Interlock functions InterlockedAdd InterlockedAnd InterlockedBitTestAndReset InterlockedBitTestAndSet InterlockedCompareExchangePointer InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedExchangePointer InterlockedIncrement InterlockedOr InterlockedXor 54

Interlock functions InterlockedAdd InterlockedAnd InterlockedBitTestAndReset InterlockedBitTestAndSet InterlockedCompareExchangePointer InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedExchangePointer InterlockedIncrement InterlockedOr InterlockedXor 55 LONG InterlockedAdd(LONG volatile* Addend, LONG Value ); Performs an atomic addition operation on the specified LONG values.

Interlock functions InterlockedAdd InterlockedAnd InterlockedBitTestAndReset InterlockedBitTestAndSet InterlockedCompareExchangePointer InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedExchangePointer InterlockedIncrement InterlockedOr InterlockedXor 56 BOOLEAN InterlockedBitTestAndSet(LONG volatile* Base, LONG Bit ); Tests the specified bit of the specified LONG value and sets it to 1. The operation is atomic.

Interlock functions InterlockedAdd InterlockedAnd InterlockedBitTestAndReset InterlockedBitTestAndSet InterlockedCompareExchangePointer InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedExchangePointer InterlockedIncrement InterlockedOr InterlockedXor 57 PVOID InterlockedCompareExchangePointer(PVOID volatile* Destination, PVOID Exchange, PVOID Comparand ); The function compares the Destination value with the Comparand value. If the Destination value is equal to the Comparand value, the Exchange value is stored in the address specified by Destination. Otherwise, no operation is performed.

Interlock functions InterlockedAdd InterlockedAnd InterlockedBitTestAndReset InterlockedBitTestAndSet InterlockedCompareExchangePointer InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedExchangePointer InterlockedIncrement InterlockedOr InterlockedXor 58 LONG InterlockedIncrement(PLONG Addend); Increments a caller-supplied variable as an atomic operation.

Critical sections void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); Initializes a critical section object. BOOL InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount ); Initializes a critical section object and sets the spin count for the critical section. 59

Critical sections void EnterCriticalSection( LPCRITICAL_SECTION pCriticalSection ); Waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership. void LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); Releases ownership of the specified critical section object. 60

Critical sections example CRITICAL_SECTION CriticalSection; int main() { if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x ) ) return 0;... // Release resources used by the critical section object. DeleteCriticalSection(&CriticalSection) } DWORD ThreadProc( LPVOID lpParameter ) {... // Request ownership of the critical section. EnterCriticalSection(&CriticalSection); // Access the shared resource. // Release ownership of the critical section. LeaveCriticalSection(&CriticalSection);... } 61

SYNCHRONISATION IN KERNEL MODE 62

Wait Functions NAME WaitForSingleObject - Waits until the specified object is in the signaled state or the time-out interval elapses. SYNOPSIS DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); 63

Wait Functions NAME WaitForMultipleObjects - Waits until one or all of the specified objects are in the signaled state or the time-out interval elapses. SYNOPSIS DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds ); 64

CloseHandle NAME CloseHandle - Closes an open object handle. SYNOPSIS BOOL CloseHandle(HANDLE hObject ); 65

Events Objects The event object is useful in sending a signal to a thread indicating that a particular event has occurred. 66

Event Functions CreateEvent OpenEvent SetEvent ResetEvent 67

CreateEvent NAME CreateEvent- Creates or opens a named or unnamed event object. SYNOPSIS HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ); 68

ResetEvent NAME ResetEvent- Sets the specified event object to the nonsignaled state. SYNOPSIS BOOL ResetEvent(HANDLE hEvent ); 69

SetEvent NAME ResetEvent- Sets the specified event object to the signaled state. SYNOPSIS BOOL SetEvent(HANDLE hEvent ); 70

Event Example HANDLE ghGlobalWriteEvent; HANDLE ghReadEvents[THREADCOUNT]; void WriteToBuffer(VOID) { DWORD dwWaitResult, i; ResetEvent(ghGlobalWriteEvent) ) dwWaitResult = WaitForMultipleObjects( THREADCOUNT, // number of handles in array ghReadEvents, // array of read-event handles TRUE, // wait until all are signaled INFINITE); // indefinite wait switch (dwWaitResult) { case WAIT_OBJECT_0: printf("Main thread writing to the shared buffer...\n"); break; default: printf("Wait error: %d\n", GetLastError()); ExitProcess(0); } SetEvent(ghGlobalWriteEvent); for(i = 0; i < THREADCOUNT; i++) SetEvent(ghReadEvents[i])); } 71 DWORD ThreadProc(LPVOID lpParam) { DWORD dwWaitResult; HANDLE hEvents[2]; hEvents[0] = *(HANDLE*)lpParam; // thread's read event hEvents[1] = ghGlobalWriteEvent; // global write event dwWaitResult = WaitForMultipleObjects( 2, // number of handles in array hEvents, // array of event handles TRUE, // wait till all are signaled INFINITE); // indefinite wait switch (dwWaitResult) { case WAIT_OBJECT_0: printf("Thread %d reading from buffer...\n", GetCurrentThreadId()); break; default: printf("Wait error: %d\n", GetLastError()); ExitThread(0); } SetEvent(hEvents[0]); return 1; }

Semaphores NAME CreateSemaphore - Creates or opens a named or unnamed semaphore object. SYNOPSIS HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName ); 72

Semaphores NAME ReleaseSemaphore - Increases the count of the specified semaphore object by a specified amount. SYNOPSIS BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount ); 73

Semaphore example HANDLE ghSemaphore; void main() { HANDLE aThread[THREADCOUNT]; DWORD ThreadID; int i; ghSemaphore = CreateSemaphore( NULL, // default security attributes MAX_SEM_COUNT, // initial count MAX_SEM_COUNT, // maximum count NULL); // unnamed semaphore for( i=0; i < THREADCOUNT; i++ ) { aThread[i] = CreateThread( NULL, // default security attributes 0, // default stack size (LPTHREAD_START_ROUTINE) ThreadProc, NULL, // no thread function arguments 0, // default creation flags &ThreadID); // receive thread identifier } WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE); for( i=0; i < THREADCOUNT; i++ ) CloseHandle(aThread[i]); CloseHandle(ghSemaphore); } DWORD WINAPI ThreadProc( LPVOID lpParam ) { DWORD dwWaitResult; BOOL bContinue=TRUE; while(bContinue) { dwWaitResult = WaitForSingleObject( ghSemaphore, // handle to semaphore 0L); // zero-second time-out interval switch (dwWaitResult) { case WAIT_OBJECT_0: bContinue=FALSE; Sleep(5); ReleaseSemaphore( ghSemaphore, // handle to semaphore 1, // increase count by one NULL) ); // not interested in previous count break; case WAIT_TIMEOUT: break; } return TRUE; } 74

Mutex NAME CreateMutex- Creates or opens a named or unnamed mutex object. SYNOPSIS HANDLE CreateMutex( PSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName ); 75

Mutex NAME ReleaseMutex - Releases ownership of the specified mutex object. SYNOPSIS BOOL ReleaseMutex(HANDLE hMutex ); 76

Mutex example 77 HANDLE ghMutex; void main() { HANDLE aThread[THREADCOUNT]; DWORD ThreadID; int i; ghMutex = CreateMutex( NULL, // default security attributes FALSE, // initially not owned NULL); // unnamed mutex for( i=0; i < THREADCOUNT; i++ ) { aThread[i] = CreateThread( NULL, // default security attributes 0, // default stack size (LPTHREAD_START_ROUTINE) WriteToDatabase, NULL, // no thread function arguments 0, // default creation flags &ThreadID); // receive thread identifier } WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE); for( i=0; i < THREADCOUNT; i++ ) CloseHandle(aThread[i]); CloseHandle(ghMutex); } DWORD WINAPI WriteToDatabase( LPVOID lpParam ) { DWORD dwCount=0, dwWaitResult; while( dwCount < 20 ) { dwWaitResult = WaitForSingleObject( ghMutex, // handle to mutex INFINITE); // no time-out interval switch (dwWaitResult) { case WAIT_OBJECT_0: __try { printf("Thread %d writing to database...\n", GetCurrentThreadId()); dwCount++; } __finally { if (! ReleaseMutex(ghMutex)) { // Deal with error. } break; case WAIT_ABANDONED: return FALSE; } return TRUE; }

Advanced Thread Objects Thread pools Fibers 78

Thank You 79