Multithread API’s
description
Transcript of Multithread API’s
![Page 1: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/1.jpg)
Multithread API’s
Adam PiotrowskiGrzegorz Jabłoński
Lecture IV
![Page 2: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/2.jpg)
Synchronisation• Mutexes• Semaphores• Condition Variables
2
![Page 3: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/3.jpg)
MutexThe 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
![Page 4: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/4.jpg)
Mutex initialisationNAME
pthread_mutex_init, pthread_mutex_destroy - initializes mutex with attr or destroys the mutex, making it unusable in any form
SYNOPSIS#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); 4
![Page 5: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/5.jpg)
Mutex unlock operationNAME
pthread_mutex_unlock - unlocks mutex and wakes up the first thread sleeping on it.
SYNOPSIS#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);
5
![Page 6: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/6.jpg)
Mutex examplethread 1add(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
![Page 7: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/7.jpg)
Mutex example
7
![Page 8: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/8.jpg)
SemaphoresA 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
![Page 9: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/9.jpg)
Semaphores initialisationNAME
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 <pthread.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);int sem_destroy(sem_t *sem);
9
![Page 10: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/10.jpg)
Semaphores operationsNAME
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 <pthread.h>
int sem_post(sem_t *sem);int sem_trywait(sem_t *sem);int sem_wait(sem_t *sem); 10
![Page 11: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/11.jpg)
Semaphores operations
11
![Page 12: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/12.jpg)
Semaphores operationsNAME
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 <pthread.h>
sem_t *sem_open(char *name, int oflag,... );int sem_close(sem_t *sem);
12
![Page 13: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/13.jpg)
Semaphors example
13
![Page 14: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/14.jpg)
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);}
![Page 15: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/15.jpg)
Conditional Variables
15
![Page 16: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/16.jpg)
Conditional Variable initialisationNAME
pthread_cond_init, pthread_cond_destroy - initializes cond with att or destroys the condition variable, making it unusable in any form.
SYNOPSIS#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, constpthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond);
16
![Page 17: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/17.jpg)
Conditional Variable Wait Operation
NAMEpthread_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 <pthread.h>
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
![Page 18: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/18.jpg)
Conditional Variable Signal Operation
NAMEpthread_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 notknow the order in which they awake.
SYNOPSIS#include <pthread.h>
int pthread_cond_signal(pthread_cond_t *cond);int pthread_cond_broadcast(pthread_cond_t *cond);
18
![Page 19: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/19.jpg)
Conditional Variable Example
thread 1pthread_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
![Page 20: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/20.jpg)
Conditional Variable Example
20
![Page 21: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/21.jpg)
Conditional Variable Examplevoid *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
![Page 22: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/22.jpg)
Multithread API’sWindows OS
22
![Page 23: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/23.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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
![Page 24: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/24.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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.
![Page 25: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/25.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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.
![Page 26: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/26.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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.
![Page 27: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/27.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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.
![Page 28: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/28.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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
![Page 29: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/29.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation );
29A pointer to the environment block for the new process.
![Page 30: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/30.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation );
30The full path to the current directory for the process.
![Page 31: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/31.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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
![Page 32: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/32.jpg)
ProcessesNAME
CreateProcess - creates a new process and its primary thread.
SYNOPSISBOOL 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.
![Page 33: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/33.jpg)
Process examplevoid _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
![Page 34: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/34.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack,
LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread );
34
![Page 35: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/35.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE 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.
![Page 36: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/36.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE 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.
![Page 37: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/37.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE 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 );
![Page 38: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/38.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE 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.
![Page 39: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/39.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack,
LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread );
39The flags that control the creation of the thread i.e. CREATE_SUSPENDED.
![Page 40: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/40.jpg)
ThreadsNAME
CreateThread- creates a thread to execute within the address space of the calling process.
SYNOPSISHANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack,
LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam, DWORD fdwCreate, LPDWORD lpIDThread );
40A pointer to a variable that receives the thread identifier.
![Page 41: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/41.jpg)
Threads - Exampleint _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
![Page 42: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/42.jpg)
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
![Page 43: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/43.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_t _beginthreadex(
void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
43
![Page 44: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/44.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_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.
![Page 45: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/45.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_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.
![Page 46: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/46.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_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.
![Page 47: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/47.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_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.
![Page 48: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/48.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_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.
![Page 49: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/49.jpg)
_beginthreadexNAME
_beginthreadex - creates a thread to execute within the address space of the calling process.
SYNOPSISuintptr_t _beginthreadex(
void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
49Points to a 32-bit variable that receives the thread identifierlist to be passed to a new thread.
![Page 50: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/50.jpg)
_beginthreadex exampleint 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
![Page 51: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/51.jpg)
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
![Page 52: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/52.jpg)
Synchronisation• Synchronisation in user mode
– Atomic access– Critical sections
• Synchronisation in kernel mode– Wait functions– Mutexes– Semphores
52
![Page 53: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/53.jpg)
SYNCHRONISATION IN USER MODE
53
![Page 54: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/54.jpg)
Interlock functions• InterlockedAdd• InterlockedAnd• InterlockedBitTestAndReset• InterlockedBitTestAndSet• InterlockedCompareExchangePointer• InterlockedDecrement• InterlockedExchange• InterlockedExchangeAdd• InterlockedExchangePointer• InterlockedIncrement• InterlockedOr • InterlockedXor
54
![Page 55: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/55.jpg)
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.
![Page 56: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/56.jpg)
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.
![Page 57: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/57.jpg)
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.
![Page 58: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/58.jpg)
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.
![Page 59: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/59.jpg)
Critical sectionsvoid 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
![Page 60: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/60.jpg)
Critical sectionsvoid 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
![Page 61: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/61.jpg)
Critical sections exampleCRITICAL_SECTION CriticalSection;
int main() {
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) ) 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
![Page 62: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/62.jpg)
SYNCHRONISATION IN KERNEL MODE
62
![Page 63: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/63.jpg)
Wait FunctionsNAME
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
![Page 64: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/64.jpg)
Wait FunctionsNAME
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
![Page 65: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/65.jpg)
CloseHandleNAME
CloseHandle - Closes an open object handle.
SYNOPSIS
BOOL CloseHandle(HANDLE hObject ); 65
![Page 66: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/66.jpg)
Events Objects• The event object is useful in
sending a signal to a thread indicating that a particular event has occurred.
66
![Page 67: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/67.jpg)
Event Functions• CreateEvent• OpenEvent• SetEvent• ResetEvent
67
![Page 68: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/68.jpg)
CreateEventNAME
CreateEvent- Creates or opens a named or unnamed event object.
SYNOPSIS
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName );
68
![Page 69: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/69.jpg)
ResetEventNAME
ResetEvent- Sets the specified event object to the nonsignaled state.
SYNOPSIS
BOOL ResetEvent(HANDLE hEvent );
69
![Page 70: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/70.jpg)
SetEventNAME
ResetEvent- Sets the specified event object to the signaled state.
SYNOPSIS
BOOL SetEvent(HANDLE hEvent );
70
![Page 71: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/71.jpg)
Event ExampleHANDLE 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;}
![Page 72: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/72.jpg)
SemaphoresNAME
CreateSemaphore - Creates or opens a named or unnamed semaphore object.
SYNOPSIS
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName );
72
![Page 73: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/73.jpg)
SemaphoresNAME
ReleaseSemaphore - Increases the count of the specified semaphore object by a specified amount.
SYNOPSIS
BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount );
73
![Page 74: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/74.jpg)
Semaphore exampleHANDLE 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
![Page 75: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/75.jpg)
MutexNAME
CreateMutex- Creates or opens a named or unnamed mutex object.
SYNOPSIS
HANDLE CreateMutex(PSECURITY_ATTRIBUTES
lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName );
75
![Page 76: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/76.jpg)
MutexNAME
ReleaseMutex - Releases ownership of the specified mutex object.
SYNOPSIS
BOOL ReleaseMutex(HANDLE hMutex );
76
![Page 77: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/77.jpg)
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; }
![Page 78: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/78.jpg)
Advanced Thread Objects• Thread pools• Fibers
78
![Page 79: Multithread API’s](https://reader036.fdocuments.in/reader036/viewer/2022062521/56814c48550346895db94d0d/html5/thumbnails/79.jpg)
Thank You
79