threads cns 3670. what is a thread? an independent unit of execution within a process a...

Post on 22-Dec-2015

237 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ThreadsThreads

CNS 3670CNS 3670

What is a thread?What is a thread?

an independent unit of execution within a process

a "lightweight process"

an independent unit of execution within a process

a "lightweight process"

How do threads relate to network programming?

How do threads relate to network programming?

Chat client:

One thread is always waiting for input from the server (via socket connection).

One thread is always waiting for input from user

Chat client:

One thread is always waiting for input from the server (via socket connection).

One thread is always waiting for input from user

Multi-threaded vs.Single-threaded

Multi-threaded vs.Single-threaded

Advantages of using more than one thread?

Advantages of using only one thread?

Advantages of using more than one thread?

Advantages of using only one thread?

Multi-threaded vs. Single-threaded

Multi-threaded vs. Single-threaded

Advantages of using more than one thread:

Single-threaded processes can't easily handle concurrent activities e.g., waiting for user I/O, network I/O, and

doing calculations at the same time Better performance if more than one

processor No guarantees Can sometimes get better performance

even if there's only one CPU. How?

Advantages of using more than one thread:

Single-threaded processes can't easily handle concurrent activities e.g., waiting for user I/O, network I/O, and

doing calculations at the same time Better performance if more than one

processor No guarantees Can sometimes get better performance

even if there's only one CPU. How?

Multi-threaded vs. Single-threaded

Multi-threaded vs. Single-threaded

Disadvantages of using more than one thread: Race conditions and deadlock One thread can accidentally modify

another's resources. Have to deal with synchronization. C and C++ threads are not portable. Concurrency can lead to worse performance

rather than better.

Disadvantages of using more than one thread: Race conditions and deadlock One thread can accidentally modify

another's resources. Have to deal with synchronization. C and C++ threads are not portable. Concurrency can lead to worse performance

rather than better.

Multi-process vs. Multi-threaded

Multi-process vs. Multi-threaded

Advantages of using more than one process?

Advantages of using more than one thread?

Advantages of using more than one process?

Advantages of using more than one thread?

Advantages of multi-threading

Advantages of multi-threading

Less overhead Switching between threads is less

expensive than switching between processes.

Sharing resources between threads is easier than sharing between processes.

Less overhead Switching between threads is less

expensive than switching between processes.

Sharing resources between threads is easier than sharing between processes.

Advantages of multi-processing

Advantages of multi-processing

Work with programs that you can't change

Write different parts of system in different programming languages e.g., GUI for chat client

Use more than one machine

Work with programs that you can't change

Write different parts of system in different programming languages e.g., GUI for chat client

Use more than one machine

Thread LibrariesThread Libraries

Java threads built-in support for threads,

synchronization pthreads: POSIX threads

UNIX/Linux Windows threads ZThreads zthread.sourceforge.net

portable C++ thread library

Java threads built-in support for threads,

synchronization pthreads: POSIX threads

UNIX/Linux Windows threads ZThreads zthread.sourceforge.net

portable C++ thread library

Creating a new threadCreating a new thread

Each thread has its own stack. Specify function that thread will

begin to execute. Member functions in C++ are a bit

tricky Pass a parameter (usually a pointer)

With pthreads, the parameter is always a pointer of type void*

Each thread has its own stack. Specify function that thread will

begin to execute. Member functions in C++ are a bit

tricky Pass a parameter (usually a pointer)

With pthreads, the parameter is always a pointer of type void*

WindowsWindows CreateThread

Win32 API Does not work right with the static C

run-time library, can cause memory leaks

_beginthread Closes thread handle

_beginthreadex Recommended function for C, C++ In C run-time library

CreateThread Win32 API Does not work right with the static C

run-time library, can cause memory leaks

_beginthread Closes thread handle

_beginthreadex Recommended function for C, C++ In C run-time library

Threads with Visual C++Threads with Visual C++ Link with LIBCMT.LIB and override default

library #define _MT in all source files that use the C

library Include <process.h> for _beginthreadex and

_endthreadex Create threads with _beginthreadex Terminate threads with _endthreadex or

simply use a return statement at the end of the thread routine.

Link with LIBCMT.LIB and override default library

#define _MT in all source files that use the C library

Include <process.h> for _beginthreadex and _endthreadex

Create threads with _beginthreadex Terminate threads with _endthreadex or

simply use a return statement at the end of the thread routine.

source: Windows System Programming, 3rd ed., by Johnson M. Hart, p. 207

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

security attributes

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

stack size:0 for same as main thread

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

start address: see next slide

unsigned Counter;unsigned __stdcall SecondThreadFunc( void* pArguments )

{printf( "In second thread…\n" );while ( Counter < 1000000 )Counter++;

_endthreadex( 0 );return 0;}

unsigned Counter;unsigned __stdcall SecondThreadFunc( void* pArguments )

{printf( "In second thread…\n" );while ( Counter < 1000000 )Counter++;

_endthreadex( 0 );return 0;}

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

pointer to argument(s)

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

start state:0 for running orCREATE_SUSPENDEND

_beginthreadex_beginthreadex

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );

HANDLE hThread;

unsigned threadID;

hThread = (HANDLE)_beginthreadex(

NULL, 0, &SecondThreadFunc,

NULL, 0, &threadID );source: http://msdn2.microsoft.com/en-us/library/kdzttdcb.aspx

pointer for thread ID

PitfallsPitfalls

Don’t make any assumptions about when threads will execute.

Don’t use reasoning like “that will hardly ever happen”.

Testing is necessary but not sufficient.

Test on a variety of systems.

Don’t make any assumptions about when threads will execute.

Don’t use reasoning like “that will hardly ever happen”.

Testing is necessary but not sufficient.

Test on a variety of systems.

PitfallsPitfalls

Only use threads when appropriate.

“Fortunately, correct programs are frequently the simplest and have the most elegant design. Complexity should be avoided wherever possible.”

Only use threads when appropriate.

“Fortunately, correct programs are frequently the simplest and have the most elegant design. Complexity should be avoided wherever possible.”

Windows System Programming, p. 223

Race ConditionRace Conditionresult of executing program(s) depends on who runs precisely whenresult of executing program(s) depends on who runs precisely when

b = getBalance(“1234”);b += 500;setBalance(“1234”, b);

b = getBalance(“1234”);

b -= 100;setBalance(“1234”, b);

Thread 1 Thread 2

balance starts at 1000

What should the ending balance be? What will it be?Will getting rid of the local variable b solve the problem?How can we solve this problem?

SynchronizationSynchronization

Need to prevent race conditions Critical region

Part of a program that accesses shared memory (or another shared resource)

To prevent race conditions, only allow one thread at a time to enter critical region

Need to prevent race conditions Critical region

Part of a program that accesses shared memory (or another shared resource)

To prevent race conditions, only allow one thread at a time to enter critical region

volatilevolatile

Optimizing compiler might leave a value in a register rather than writing it back to memory.

Declare as volatile so that the variable will always be written to memory when changed and read from memory when accessed.

Optimizing compiler might leave a value in a register rather than writing it back to memory.

Declare as volatile so that the variable will always be written to memory when changed and read from memory when accessed.

Windows SynchronizationWindows Synchronization

CRITICAL_SECTION WaitForSingleObject File locks Mutexes Semaphores Events

CRITICAL_SECTION WaitForSingleObject File locks Mutexes Semaphores Events

CRITICAL_SECTIONCRITICAL_SECTION

Used to define a section of code that only one thread can execute at a time.

Initialized and deleted, but do not have handles. Cannot be shared with other processes.

Spend as little time as possible in CS.

Used to define a section of code that only one thread can execute at a time.

Initialized and deleted, but do not have handles. Cannot be shared with other processes.

Spend as little time as possible in CS.

CRITICAL_SECTIONCRITICAL_SECTION

CRITICAL_SECTION cs1;volatile DWORD N = 0;InitializeCriticalSection(&cs1);...EnterCriticalSection(&cs1);// ...use NLeaveCriticalSection(&cs1);...DeleteCriticalSection(&cs1);

Windows System Programming, p. 239

MutexesMutexes

Short for “mutual exclusion” Can be used by threads in

separate processes Allow time-out values Become signaled when abandoned

by a terminating process

Short for “mutual exclusion” Can be used by threads in

separate processes Allow time-out values Become signaled when abandoned

by a terminating process

Mutex functionsMutex functions

CreateMutex ReleaseMutex OpenMutex A thread locks a mutex by calling WaitForSingleObject or WaitForMultipleObjects

CreateMutex ReleaseMutex OpenMutex A thread locks a mutex by calling WaitForSingleObject or WaitForMultipleObjects

Using a mutexUsing a mutexHandle mutex;volatile DWORD N = 0;mutex = CreateMutex(NULL, false, “m1”);...WaitForSingleObject(mutex, INFINITE);// ...use NReleaseMutex(mutex);...CloseHandle(mutex);// The mutex will be destroyed when the// last handle is closed, or when the// process terminates.

based on code from Windows System Programming, p. 248

Mutexes vs. CRITICAL_SECTIONs

Mutexes vs. CRITICAL_SECTIONs

Abandoned mutexes are signaled Mutex waits can time out Mutexes can be shared with other

processes You can use WaitForMultipleObjects

with mutexes (avoid deadlock) Can get immediate ownership of

mutex CSs are usually faster and simpler

Abandoned mutexes are signaled Mutex waits can time out Mutexes can be shared with other

processes You can use WaitForMultipleObjects

with mutexes (avoid deadlock) Can get immediate ownership of

mutex CSs are usually faster and simpler

DeadlockDeadlock

Circular wait e.g., Breakfasting Kindergarteners,

pirate map

Order access to resources All or nothing requests for resources

Must get everything requested or nothing

Circular wait e.g., Breakfasting Kindergarteners,

pirate map

Order access to resources All or nothing requests for resources

Must get everything requested or nothing

top related