multithreading programming

53
Multithreading Multithreading Programming Programming Yung-Pin Cheng Yung-Pin Cheng

Upload: helga

Post on 20-Mar-2016

73 views

Category:

Documents


0 download

DESCRIPTION

Multithreading Programming. Yung-Pin Cheng. History. In the past (

TRANSCRIPT

Page 1: Multithreading Programming

Multithreading Multithreading ProgrammingProgramming

Yung-Pin ChengYung-Pin Cheng

Page 2: Multithreading Programming

HistoryHistory

In the past (<10 years), when there was In the past (<10 years), when there was no multithreading support from O.S., how no multithreading support from O.S., how a server (such as telnet, BBS server) is a server (such as telnet, BBS server) is implemented? implemented? The era of multi-process programmingThe era of multi-process programming

Page 3: Multithreading Programming

Unix’s Unix’s fork()fork() revisited revisited

Page 4: Multithreading Programming

An example of Unix fork()An example of Unix fork()

void main() { printf(“hello”); fork(); printf(“bye”);}

hellobyebye

The output

Page 5: Multithreading Programming

How How fork()fork() is implemented in Unix? is implemented in Unix?

Process’s Image in Memory

void main() { printf(“hello”); fork(); printf(“bye”);}

_TEXT(code)

_DATA(code)

PC(Programcounter)

void main() { printf(“hello”); fork(); printf(“bye”);}

_TEXT(code)

_DATA(code)

PC(Programcounter) copy

Page 6: Multithreading Programming

fork()fork() example again example again

void main() { if (fork() == 0) printf(“ in the child process”); else printf(“ in the parent process”);}

Page 7: Multithreading Programming

An old-fashioned concurrent serverAn old-fashioned concurrent server

main() {main() {// create a TCP/IP socket to use// create a TCP/IP socket to uses =s =socketsocket(PF_INET,SOCK_STREAM ,0);(PF_INET,SOCK_STREAM ,0);

// bind the server address// bind the server addressZ =Z = bind bind(s, (struct sockaddr *)&adr_srvr, len_inet);(s, (struct sockaddr *)&adr_srvr, len_inet);

// make it a listening socket// make it a listening socketZ = Z = listenlisten(s, 10);(s, 10);

// start the server loop// start the server loopfor (;;) {for (;;) { // wait for a connect // wait for a connect c = c = acceptaccept(s, (struct sockaddr*) &adr_clnt,& le(s, (struct sockaddr*) &adr_clnt,& le

n_int);n_int);

PID = fork();PID = fork(); if (PID > 0) {if (PID > 0) { // parent process// parent process close(c);close(c); continue ; continue ; }} // child process // child process rx = fdopen(c,”r”);rx = fdopen(c,”r”); tx = fdopen(dup(c), “w”);tx = fdopen(dup(c), “w”);

// process client’s request// process client’s request …… …….... fclose(tx); fclose(rx);fclose(tx); fclose(rx); exit(0);exit(0);}}

Page 8: Multithreading Programming

Problems with old-fashioned multi-Problems with old-fashioned multi-processes programmingprocesses programming

Context switching overhead is highContext switching overhead is highCommunications between forked processeCommunications between forked processes also has high costs also has high cost typical mechanism – via typical mechanism – via IPC (interprocess coIPC (interprocess co

mmunication)mmunication) such as such as shared memory, semapshared memory, semaphore, message queuehore, message queue

these are cross address space communicatiothese are cross address space communicationn

invoking of IPC cause mode switch – invoking of IPC cause mode switch – may caumay cause a process to block.se a process to block.

Page 9: Multithreading Programming

The concept of a The concept of a processprocessHowever, processes are still the very basic However, processes are still the very basic element in O.S.element in O.S. UNIT of resources ownershipUNIT of resources ownership

Allocated with virtual address space + control of other Allocated with virtual address space + control of other resources such as I/O, files….resources such as I/O, files….

Unit of dispatchingUnit of dispatchingAn execution paths (may interleaved with other An execution paths (may interleaved with other processes)processes)An execution state, dispatching priority.An execution state, dispatching priority.Controlled by OSControlled by OS

Page 10: Multithreading Programming

Now, What is a thread?Now, What is a thread?

A thread is an execution path in the code A thread is an execution path in the code segmentsegmentO.S. provide an individual Program O.S. provide an individual Program Counter (PC) for each execution pathCounter (PC) for each execution path

Page 11: Multithreading Programming

An exampleAn example

main() {main() {// create a TCP/IP socket to use// create a TCP/IP socket to uses =s =socketsocket(PF_INET,SOCK_STREAM ,0);(PF_INET,SOCK_STREAM ,0);

// bind the server address// bind the server addressZ =Z = bind bind(s, (struct sockaddr *)&adr_srvr, len_inet);(s, (struct sockaddr *)&adr_srvr, len_inet);

// make it a listening socket// make it a listening socketZ = Z = listenlisten(s, 10);(s, 10);

// start the server loop// start the server loopfor (;;) {for (;;) { // wait for a connect // wait for a connect c = c = acceptaccept(s, (struct sockaddr*) &adr_clnt,& le(s, (struct sockaddr*) &adr_clnt,& le

n_int);n_int);

PID = fork();PID = fork(); if (PID > 0) {if (PID > 0) { // parent process// parent process close(c);close(c); continue ; continue ; }} // child process // child process rx = fdopen(c,”r”);rx = fdopen(c,”r”); tx = fdopen(dup(c), “w”);tx = fdopen(dup(c), “w”);

// process client’s request// process client’s request …… …….... fclose(tx); fclose(rx);fclose(tx); fclose(rx); exit(0);exit(0);}}

PC

Page 12: Multithreading Programming

CommentsComments

Traditional program is one thread per Traditional program is one thread per process.process.The main thread starts with The main thread starts with main()main()Only one thread (or, program counter) is Only one thread (or, program counter) is allowed to execute the code segmentallowed to execute the code segmentTo add a new PC, you need to To add a new PC, you need to fork() fork() to to have another PC to execute have another PC to execute in another in another process address space.process address space.

Page 13: Multithreading Programming

MultithreadingMultithreading

The ability of an OS to support multiple thrThe ability of an OS to support multiple threads of execution within a single process eads of execution within a single process (many program counters in a code segme(many program counters in a code segment)nt)Windows support multithreading earlier (miWindows support multithreading earlier (mid 1990)d 1990)SunOS, Linux came lateSunOS, Linux came late

Page 14: Multithreading Programming

The example againThe example again

main() {main() {// create a TCP/IP socket to use// create a TCP/IP socket to uses =s =socketsocket(PF_INET,SOCK_STREAM ,0);(PF_INET,SOCK_STREAM ,0);

// bind the server address// bind the server addressZ =Z = bind bind(s, (struct sockaddr *)&adr_srvr, len_inet);(s, (struct sockaddr *)&adr_srvr, len_inet);

// make it a listening socket// make it a listening socketZ = Z = listenlisten(s, 10);(s, 10);

// start the server loop// start the server loopfor (;;) {for (;;) { // wait for a connect // wait for a connect c = c = acceptaccept(s, (struct sockaddr*) &adr_clnt,& le(s, (struct sockaddr*) &adr_clnt,& le

n_int);n_int);

hThrd = createThread(Threadfunc,…)hThrd = createThread(Threadfunc,…) close(c);close(c); continue ; continue ; }}}}ThreadFunc() {ThreadFunc() { // child process // child process rx = fdopen(c,”r”);rx = fdopen(c,”r”); tx = fdopen(dup(c), “w”);tx = fdopen(dup(c), “w”);

// process client’s request// process client’s request …… …….... fclose(tx); fclose(rx);fclose(tx); fclose(rx); exit(0);exit(0);}}

PC

PCPCPC

Page 15: Multithreading Programming

Possible combination of thread and processesPossible combination of thread and processes

One process one threadOne process multiple thread

Multiple processes multipleThreads per process

Multiple processesOne thread per process

Page 16: Multithreading Programming

Process is still there, what’s new for Process is still there, what’s new for thread?thread?

With processWith process Virtual address space (holding process image)Virtual address space (holding process image) Protected access to CPU, files, and I/O resourcesProtected access to CPU, files, and I/O resourcesWith thread (each thread has its own..)With thread (each thread has its own..) Thread execution stateThread execution state Saved thread context (an independent PC within a Saved thread context (an independent PC within a

process)process) An execution stackAn execution stack Per-thread static storage for local variablePer-thread static storage for local variable Access to memory and resource of its process, Access to memory and resource of its process,

shared with all other threads in that processshared with all other threads in that process

Page 17: Multithreading Programming

Single threaded and multithreaded modelSingle threaded and multithreaded model

UserAddress

space

PCB

UserAddressspace

PCB

Userstack

Kernelstack

Userstack

Kernelstack

Userstack

Kernelstack

Userstack

Kernelstack

ThreadControlblock

ThreadControlblock

ThreadControlblock

Single-threadedprocess

MultithreadProcess model

Page 18: Multithreading Programming

Key benefits of multithreadingKey benefits of multithreading

Less time to create a thread than a Less time to create a thread than a processprocessLess time to terminate a thread than a Less time to terminate a thread than a processprocessLess time to switch a threadLess time to switch a threadEnhance efficiency in communication: Enhance efficiency in communication: no need for kernel to interveneno need for kernel to intervene MACH shows a factor of 10MACH shows a factor of 10

Page 19: Multithreading Programming

Boosted by SMPBoosted by SMP

If you install SMP motherboard and SMP If you install SMP motherboard and SMP enhanced O.S. kernel ( Windows and enhanced O.S. kernel ( Windows and Linux both support)Linux both support)Each thread can be assign to an individual Each thread can be assign to an individual CPU.CPU.The result – boosted performance The result – boosted performance

Page 20: Multithreading Programming

Java threadsJava threadsclass javathread extends Thread {class javathread extends Thread {int _threadindex ;int _threadindex ;int x;int x;static int threadno ; static int threadno ; // constructor// constructorjavathread(int threadindex) {javathread(int threadindex) { _threadindex = threadindex ;_threadindex = threadindex ; threadno ++ ;threadno ++ ;}}run() {run() { for (int i; i<10000; i++) for (int i; i<10000; i++) x ++ ;x ++ ; System.out.printlnSystem.out.println (“this is thread “ + _threadindex + “of” (“this is thread “ + _threadindex + “of” threadnothreadno}}

POSSIBLE OUTPUT:POSSIBLE OUTPUT:

This is main thread !This is main thread !This is thread 1 of 2This is thread 1 of 2This is thread 2 of 2This is thread 2 of 2

void main() {void main() { Thread t1 = new javathread(1);Thread t1 = new javathread(1); Thread t2 = new javathread(2);Thread t2 = new javathread(2); t1.start();t1.start(); t2.start();t2.start(); System.out.println(“This is maiSystem.out.println(“This is mai

n thread\n”);n thread\n”);}}

Like a global variable in C,

C++

Page 21: Multithreading Programming

javathread(int threadindex) { _threadindex = threadindex ; threadno ++ ;}

run() { for (int i; i<10000; i++) x ++ ; System.out.println (“this is thread “ + _threadindex + “of” + threadno ); }void main() { Thread t1 = new javathread(1); Thread t2 = new javathread(2); t1.start(); t2.start();}

codecodesegmentsegment

int threadno ;int threadno ;

data data segmentsegment

(0) _threadindex(0) _threadindex(4) x(4) x

(0) _threadindex(0) _threadindex(4) x(4) x

t1baset1base

t2baset2base

mov ax, [ESP+4];mov ax, [ESP+4];mov [ESI+0], eax;mov [ESI+0], eax;mov eax, threadnomov eax, threadnoinc eax ;inc eax ;mov threadno,eaxmov threadno,eax

ESIESI

heap area

Page 22: Multithreading Programming

Win32 Thread – an exampleWin32 Thread – an exampleint main() {int main() {

HANDLE hThrd ;HANDLE hThrd ;DWORD threadid ;DWORD threadid ;int i ;int i ;for (i=0;i<5;i++) {for (i=0;i<5;i++) { hThrd = hThrd = CreateThread(NULL,0,ThreadFunc,(LPVOID)I,0,&threadid);CreateThread(NULL,0,ThreadFunc,(LPVOID)I,0,&threadid); if (hThr) printf(“Thread launched %d\n”,i);if (hThr) printf(“Thread launched %d\n”,i);}}Sleep(2000);Sleep(2000);return EXIT_SUCCESS;return EXIT_SUCCESS;

}}DWORD WINAPI ThreadFunc(LPVOID n) {DWORD WINAPI ThreadFunc(LPVOID n) {

int i ;int i ; for (i=0;i<10;i++) {for (i=0;i<10;i++) { printf(“%d%d%d%d%d%d%d%d\n”, n,n,n,n,n,n,n,n);printf(“%d%d%d%d%d%d%d%d\n”, n,n,n,n,n,n,n,n);

}}

Page 23: Multithreading Programming

possible outputpossible output00000000000000Thread lauchedThread lauched1111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222Thread lauched Thread lauched

00000000000000Thread lauchedThread lauched1111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222Thread lauched Thread lauched

333333333333333333333333333333333333333333333344444443333444444444444444444444444444444444444444444444444433333333333333333333333333333333333333333333333333

Contextswitch may occurs in the middle of printf command- a type of race condition

Page 24: Multithreading Programming

NOTESNOTES

In multi-threading, typically you have no control In multi-threading, typically you have no control of output sequences or of output sequences or schedulingschedulingContext switching may occur in any timeContext switching may occur in any time the probility may be the probility may be 1/100000001/10000000 but consider how ma but consider how ma

ny instruction CPU may execute per secondny instruction CPU may execute per second

Your program become concurrent and Your program become concurrent and nondeternondeterministic.ministic. Same input to a concurrent program may generate difSame input to a concurrent program may generate dif

ferent outputferent output beware of the beware of the probe effectprobe effect

Page 25: Multithreading Programming

race conditionrace condition

AddHead(struct List *list, AddHead(struct List *list, struct Node *node){struct Node *node){ node->next = list->head ;node->next = list->head ; list->head = node;list->head = node;}}

Thread 1 Thread 2

……....AddHead(list,B)AddHead(list,B)……....

……....AddHead(list,C)AddHead(list,C)……....

Page 26: Multithreading Programming

race condition- race condition- if you think you are smart if you think you are smart enough, things still go wrongenough, things still go wrong

AddHead(struct List *list, AddHead(struct List *list, struct Node *node){struct Node *node){ while (flag !=0) ;while (flag !=0) ; flag = 1 ;flag = 1 ; node->next = list->head ;node->next = list->head ; list->head = node;list->head = node; flag = 0;flag = 0;}}

xor eax, eax ;xor eax, eax ;; while (flag !=0) ; while (flag !=0) L86: L86: cmp _flag, eaxcmp _flag, eax jne L86jne L86; flag = 1 ; flag = 1 mov eax, _list$[esp-4]mov eax, _list$[esp-4] mov ecx, _node$[esp-4]mov ecx, _node$[esp-4] mov _flag, 1mov _flag, 1; node->next = list->head; node->next = list->head mov edx, [eax]mov edx, [eax] mov [ecx], edxmov [ecx], edx; list->head; list->head mov [eax] , ecxmov [eax] , ecx ; flag = 0; flag = 0 mov _flag,0mov _flag,0

Page 27: Multithreading Programming

What is C runtime library – multi-threaded What is C runtime library – multi-threaded versionversion

Original C runtime library is not suitable for Original C runtime library is not suitable for multithreaded programmultithreaded programOriginal C runtime library uses many Original C runtime library uses many global variables and static variables -> global variables and static variables -> cause multithreads to racecause multithreads to race

Page 28: Multithreading Programming

NOTESNOTES

conventional C library is not made to execconventional C library is not made to execute under multithreaded programute under multithreaded programchoose the right C runtime library to linkchoose the right C runtime library to link /ML Single-threaded/ML Single-threaded /MT Multi-threaded (static)/MT Multi-threaded (static) /MD Multi-threaded DLL/MD Multi-threaded DLL /MLd Debug Single-threaded/MLd Debug Single-threaded /MTd Debug Multithreaded (static)/MTd Debug Multithreaded (static) /MDd Debug Multithreaded (DLL)/MDd Debug Multithreaded (DLL)

Page 29: Multithreading Programming

CloseHandleCloseHandleint main() {int main() {

HANDLE hThrd ;HANDLE hThrd ;DWORD threadid ;DWORD threadid ;int i ;int i ;for (i=0;i<5;i++) {for (i=0;i<5;i++) { hThrd = hThrd = CreateThread(NULL,0,ThreadFunc,(LPVOID)I,0,&threadiCreateThread(NULL,0,ThreadFunc,(LPVOID)I,0,&threadi

dd);); if (hThr) {if (hThr) { printf(“Thread launched %d\n”,i);printf(“Thread launched %d\n”,i); CloseHandle(hThrd)CloseHandle(hThrd)}}Sleep(2000);Sleep(2000);return EXIT_SUCCESS;return EXIT_SUCCESS;

}}

Page 30: Multithreading Programming

CloseHandleCloseHandle

Thread is a kernel object Thread is a kernel object A kernel object can be owned by several ownersA kernel object can be owned by several ownersEach thread when created is owned by two Each thread when created is owned by two owner- owner- the creator and the thread itselfthe creator and the thread itself. So, the . So, the reference count is two.reference count is two.When reference count is down to zeroWhen reference count is down to zero, windows , windows destroy the object.destroy the object.if a process generate many threads but do not if a process generate many threads but do not close the handle, this process may own many close the handle, this process may own many kernel thread object -> kernel thread object -> resource leaksresource leaks

Page 31: Multithreading Programming

Some suggestionsSome suggestions

avoid using global variables among avoid using global variables among threadsthreadsdo not share GDI objects between threaddo not share GDI objects between threadmake sure you know the status of the make sure you know the status of the threads you create, do not exit without threads you create, do not exit without waiting your threads to terminatewaiting your threads to terminatehave the main thread to handle UI (user have the main thread to handle UI (user interface)interface)

Page 32: Multithreading Programming

Misc Win32 functionMisc Win32 function

BOOL GetExitCodeThreadBOOL GetExitCodeThread A non-blocked system call to acquire the statuA non-blocked system call to acquire the statu

s of a threads of a threadVOID ExitThreadVOID ExitThreadDWORD WaitForSingleObjectDWORD WaitForSingleObject avoid busy waitingavoid busy waiting e.g. WaitForSingleObject(hThrd, INFINITE);e.g. WaitForSingleObject(hThrd, INFINITE);DWORD WaitForMultipleObjectsDWORD WaitForMultipleObjects same as WaitForSingleObjectsame as WaitForSingleObject

Page 33: Multithreading Programming

SynchronizationSynchronizationThere are few kinds multithreaded applications There are few kinds multithreaded applications which do not need synchronizations among threwhich do not need synchronizations among threads.ads.e.g., e.g., telnettelnet and and bbsbbs daemon. daemon.if your threads do not need any kind of synchroniif your threads do not need any kind of synchronization, such as telnet, you are lucky to get away zation, such as telnet, you are lucky to get away with with sync horrorsync horror..Once you need synchronization, you invite concOnce you need synchronization, you invite concurrency errors to your program.urrency errors to your program. deadlockdeadlock race conditionsrace conditions starvationstarvation

Page 34: Multithreading Programming

Concurrency errorsConcurrency errorsare known to be are known to be

hard to detect (irreproducible)hard to detect (irreproducible) hard to debug (probe effect)hard to debug (probe effect) hard to get a correct fixhard to get a correct fix

Currently, there is no effective way to detect, debugCurrently, there is no effective way to detect, debugYour better choice is Your better choice is

be careful at the beginning (spend more time in design stage)be careful at the beginning (spend more time in design stage) use the simplest synchronization structure that cannot be wrong use the simplest synchronization structure that cannot be wrong

or proved to be corrector proved to be correct do not use complicated synchronization structure unless you are do not use complicated synchronization structure unless you are

sure what you are doingsure what you are doing sacrifices some performance in exchange of correctnesssacrifices some performance in exchange of correctness..

Page 35: Multithreading Programming

Synchronization mechanism in Synchronization mechanism in Win32Win32

Critical sectionsCritical sectionsMutexesMutexesSemaphoreSemaphore

Page 36: Multithreading Programming

Critical SectionsCritical Sections

VOID InitializeCriticalSectionVOID InitializeCriticalSectionVOID DeleteCriticalSectionVOID DeleteCriticalSectionVOID EnterCriticalSectionVOID EnterCriticalSectionVOID LeaveCriticalSectionVOID LeaveCriticalSection

Page 37: Multithreading Programming

AddHead(struct List *plist, AddHead(struct List *plist, struct Node *node){struct Node *node){ EnterCriticalSection(&plist->critical_sec);EnterCriticalSection(&plist->critical_sec); node->next = list->head ;node->next = list->head ; list->head = node;list->head = node; LeaveCriticalSection(&plist->critical_sec):LeaveCriticalSection(&plist->critical_sec):}}

typedef struct _Node {typedef struct _Node { struct _Node *next ;struct _Node *next ; int data ;int data ;} Node ;} Node ;typedef struct _List { typedef struct _List { Node *head ;Node *head ; CRITICAL_SECTION critical_sec ;CRITICAL_SECTION critical_sec ;} List ;} List ;

List *CreateList() {List *CreateList() { List *plist = malloc(sizeof(pList));List *plist = malloc(sizeof(pList)); pList-> head = NULL ;pList-> head = NULL ; InitializeCriticalSection(&pList->critical_sec);InitializeCriticalSection(&pList->critical_sec); return pList ;return pList ;}}

Page 38: Multithreading Programming

AddHead(struct List *plist, AddHead(struct List *plist, struct Node *node){struct Node *node){ EnterCriticalSection(&plist->critical_sec);EnterCriticalSection(&plist->critical_sec); node->next = list->head ;node->next = list->head ; list->head = node;list->head = node; LeaveCriticalSection(&plist->critical_sec):LeaveCriticalSection(&plist->critical_sec):}}

Thread 1

…..AddHead(list,A)……

Thread 2

……AddHead(list,B)……

Page 39: Multithreading Programming

ContinuedContinued

There is at most one thread can There is at most one thread can manipulate the linked listmanipulate the linked listdo not use do not use sleep()sleep() or or Wait..()Wait..() in a critical in a critical section -> cause deadlocksection -> cause deadlockif a thread enter a critical section and exit, if a thread enter a critical section and exit, the critical section is locked by Window NTthe critical section is locked by Window NT

Page 40: Multithreading Programming

DeadlockDeadlockvoid SwapLists(List *list1, List *list2) {void SwapLists(List *list1, List *list2) { List *tmp_list ;List *tmp_list ; EnterCriticalSection(list1-> critical_sec);EnterCriticalSection(list1-> critical_sec); EnterCriticalSection(list2->critical_sec);EnterCriticalSection(list2->critical_sec); tmp_list = list1->headtmp_list = list1->head list1->head = list2->headlist1->head = list2->head list2->head = tmp_list ;list2->head = tmp_list ; LeaveCriticalSection(list1->critical_sec);LeaveCriticalSection(list1->critical_sec); LeaveCriticalSection(list2->critical_sec);LeaveCriticalSection(list2->critical_sec);}}

• Holding a resouce and then request another resource -> possible deadlock

Page 41: Multithreading Programming

void SwapLists(List *list1, List *list2) {void SwapLists(List *list1, List *list2) { List *tmp_list ;List *tmp_list ; EnterCriticalSection(list1-> critical_sec);EnterCriticalSection(list1-> critical_sec); EnterCriticalSection(list2->critical_sec);EnterCriticalSection(list2->critical_sec); tmp_list = list1->headtmp_list = list1->head list1->head = list2->headlist1->head = list2->head list2->head = tmp_list ;list2->head = tmp_list ; LeaveCriticalSection(list1->critical_sec);LeaveCriticalSection(list1->critical_sec); LeaveCriticalSection(list2->critical_sec);LeaveCriticalSection(list2->critical_sec);}}

Thread 1

……

Swap_lists…………

Thread 2…………Swap_lists…….…….

Page 42: Multithreading Programming

Mutex (MUTual EXclusion)Mutex (MUTual EXclusion)

Similar to critical sectionSimilar to critical sectioncause 100 times of time to lock a process/tcause 100 times of time to lock a process/threadhread CS is executed in user mode (only within a prCS is executed in user mode (only within a pr

ocess)ocess) mutex is executed in kernel mode , it can crosmutex is executed in kernel mode , it can cros

s process (interprocess communication)s process (interprocess communication)

Page 43: Multithreading Programming

Comparision of CS/MutexComparision of CS/Mutex

CreateMutexCreateMutexOpenMutexOpenMutex

WaitForSingleObject()WaitForSingleObject()WaitForMultipleObject()WaitForMultipleObject()MsgWaitForMultipleObjectMsgWaitForMultipleObject

ReleaseMutexReleaseMutex

CloseHandleCloseHandle

VOID InitializeCriticalSectionVOID InitializeCriticalSection

VOID EnterCriticalSectionVOID EnterCriticalSection

VOID LeaveCriticalSectionVOID LeaveCriticalSection

VOID DeleteCriticalSectionVOID DeleteCriticalSection

Page 44: Multithreading Programming

typedef struct _Node {typedef struct _Node { struct _Node *next ;struct _Node *next ; int data ;int data ;} Node ;} Node ;typedef struct _List { typedef struct _List { Node *head ;Node *head ; HANDLE hMutex ;HANDLE hMutex ;} List ;} List ;

List *CreateList() {List *CreateList() { List *plist = malloc(sizeof(pList));List *plist = malloc(sizeof(pList)); pList-> head = NULL ;pList-> head = NULL ; plist->hMutex = CreateMutex(NULL,false,NULL)plist->hMutex = CreateMutex(NULL,false,NULL) return pList ;return pList ;}}

void SwapLists(List *list1, List *list2) {void SwapLists(List *list1, List *list2) { List *tmp_list ;List *tmp_list ; HANDLE arrhandles[2] ;HANDLE arrhandles[2] ; arrhandles[0] = list1-> hMutex ;arrhandles[0] = list1-> hMutex ; arrhandles[1] = list2-> hMutex ;arrhandles[1] = list2-> hMutex ; WaitForMultipleObjects(2, arrhandles, TRUE, INFINITE);WaitForMultipleObjects(2, arrhandles, TRUE, INFINITE); tmp_list = list1->headtmp_list = list1->head list1->head = list2->headlist1->head = list2->head list2->head = tmp_list ;list2->head = tmp_list ; ReleaseMutex(arrhandles[0]);ReleaseMutex(arrhandles[0]); ReleaseMutex(arrhandles[1]);ReleaseMutex(arrhandles[1]);}}

Page 45: Multithreading Programming

NOTESNOTES

When a When a mutexmutex is created, no thread/proce is created, no thread/process have a lock on it, ss have a lock on it, it is ready to triggerit is ready to trigger So, a call to Wait..() will immediately return, otSo, a call to Wait..() will immediately return, ot

herwise a call to Wait…() will be blocked.herwise a call to Wait…() will be blocked.

mutex is exactly the same as a semaphore mutex is exactly the same as a semaphore with semaphore value 1.with semaphore value 1.

Page 46: Multithreading Programming

SemaphoreSemaphore

Synchronization tool (provided by the OS) that do not require busy waiting

A semaphore S is an integer variable that, apart from initialization, can only be accessed through 2 atomic and mutually exclusive operations:– P(S), down(S), wait(S)– V(S), up(S), signal(S)

To avoid busy waiting: when a process has to wait, it will be put in a blocked queue of processes waiting for the same event

Page 47: Multithreading Programming

Semaphores in Win32Semaphores in Win32

HANDLE CreateSemaphoreHANDLE CreateSemaphorevoid WaitForSingleObject ( like P())void WaitForSingleObject ( like P())BOOL ReleaseSemaphore (like V())BOOL ReleaseSemaphore (like V())

They are the same as the semaphore taugThey are the same as the semaphore taught in O.S.ht in O.S.use Wait…() to decrease a semaphore or use Wait…() to decrease a semaphore or block a thread when its value is zero.block a thread when its value is zero.

Page 48: Multithreading Programming

Semaphore implementationSemaphore implementationP(S): S.count--; if (S.count<0) { block this process place this process in S.queue }

V(S): S.count++; if (S.count<=0) { remove a process P from S.queue place this process P on ready list }

S.count must be initialized to a nonnegative value (depending on application)

Page 49: Multithreading Programming

Using semaphores for solving critical section problems

For n processesInitialize S.count to 1Then only 1 process is allowed into CS (mutual exclusion)To allow k processes into CS, we initialize S.count to k

Process Pi:repeat P(S); CS V(S); RSforever

Page 50: Multithreading Programming

Problems with semaphores

semaphores provide a powerful tool for enforcing mutual exclusion and coordinate processesBut P(S) and V(S) are scattered among several processes. Hence, difficult to understand their effectsUsage must be correct in all the processesOne bad (or malicious) process can fail the entire collection of processes

Page 51: Multithreading Programming

IMPORTANT:IMPORTANT:Suggestion and TrenSuggestion and Trendd

The current trend of synchronization is called The current trend of synchronization is called sysynchronized shared objectsnchronized shared objectsDo not use semaphore in thread’s main programDo not use semaphore in thread’s main program/function, it is difficult to debug/function, it is difficult to debuggather all the semaphore, mutex, critical sectiongather all the semaphore, mutex, critical sections in an shared object’s methodss in an shared object’s methodsThread’s main function need not worry about the Thread’s main function need not worry about the synchronizationsynchronizationLet the shared object implementer (usually an exLet the shared object implementer (usually an experienced personel in concureent programming) perienced personel in concureent programming) worry about the synchronizationworry about the synchronization

Page 52: Multithreading Programming

Synchronization via a shared object Synchronization via a shared object in Java in Java

class PRODUCER class PRODUCER extends Thread {extends Thread {buffer b ; // the shared objectbuffer b ; // the shared objectPRODUCER(buffer _b) PRODUCER(buffer _b) { b = _b ; }{ b = _b ; }run() {run() { do {do { data = generate_a_data();data = generate_a_data(); b.append(data);b.append(data); } while (1);} while (1);} }

class CONSUMER class CONSUMER extends Thread {extends Thread {buffer b ; // the shared objectbuffer b ; // the shared objectCONSUMER(buffer _b) CONSUMER(buffer _b) { b = _b ; }{ b = _b ; }run() {run() { do {do { b.take(data);b.take(data); output data ;output data ; } while (1);} while (1);} }

main() {main() { buffer rb = new buffer() ;buffer rb = new buffer() ; Thread p = new PRODUCER(rb);Thread p = new PRODUCER(rb); Thread c = new CONSUMER(rb);Thread c = new CONSUMER(rb); p.start();p.start(); c.start();c.start();

class buffer {class buffer {??}}

Page 53: Multithreading Programming

Let’s do it with handLet’s do it with hand