CS204 : Advanced C Prog' Threads - PowerPoint PPT Presentation

1 / 40
About This Presentation
Title:

CS204 : Advanced C Prog' Threads

Description:

Suspending/Resuming Threads. Terminating/Exiting Threads ... Suspending and Resuming Thread Execution ... thread, when it is resumed it starts the execution ... – PowerPoint PPT presentation

Number of Views:69
Avg rating:3.0/5.0
Slides: 41
Provided by: Ekr9
Category:

less

Transcript and Presenter's Notes

Title: CS204 : Advanced C Prog' Threads


1
CS-204 Advanced C Prog.Threads
2
Motivation
  • You are assigned to implement a web server which
    will handle multiple user connections at the same
    time,
  • You do not know in advance how many users will
    connect to your web server
  • You do not know how the interaction will be
    between your server and the user (some users just
    connect to your server but do not interact with
    it)
  • You need to share the CPU time equally between
    the connections (your clients)
  • You can not block one user to get an interaction
    request from another

3
Motivation
  • You are implementing a 3D multiplayer game, and
    you need to be responsive to each player. How can
    you do this ? While waiting for the first
    players input, how can you let the second player
    to do something ?
  • Or you are implementing an image processor which
    has a GUI, and your program uses a heavy-weight
    function which takes a considerable amount of
    time to return, how can you redraw the GUI and
    handle user interactions while this function does
    its job ?

4
Motivation
  • Basically, when you are doing something that
    blocks the CPU, you will need threads (which will
    manage the CPU usage among multiple requests)
  • Similarly, if you have a big job, multiple
    processors
  • it would be easier to divide a heavy job into
    smaller ones and let each processor do some
    portion of it and then combine the result.

5
General Description
  • Thread is a unit of execution that accomplishes a
    task
  • A thread belongs to a process. It can not live on
    its own.
  • Each process has at least one running thread
    (primary).
  • Thread ? Task
  • Read numbers from a file
  • Display graphical user interface
  • Do mathematical calculations
  • ...
  • At each instant, the CPU is addressing only one
    thread, but by rotating among threads, it gives
    the feeling that each thread is handled
    simultaneously

6
Thread vs. Process
  • Both threads and processes are methods of
    parallelizing an application.
  • However, processes are independent execution
    units that contain their own state information,
    use their own address spaces, and only interact
    with each other via interprocess communication
    mechanisms.
  • By contrast, a thread is a coding construct. A
    single process might contain multiple threads
    all threads within a process share the same state
    and same memory space, and can communicate with
    each other directly, because they share the same
    variables

7
Thread vs. Process
  • Per Process Items
  • Address Space
  • Global Variables
  • Open Files
  • Child Processes
  • Signals
  • Accounting Info.
  • Per Thread Items
  • Program Counter
  • Registers
  • Stack
  • Thread State
  • Signals

8
Thread vs. Process
  • Each process provides the resources needed to
    execute a program. A process has,
  • A virtual address space,
  • Executable code,
  • Open handles to system objects,
  • A unique process identifier,
  • Environment variables,
  • A priority class,
  • And at least one thread of execution.
  • Each process is started with a single thread,
    often called the primary thread, but can create
    additional threads from any of its threads.

9
Thread vs. Process
  • A thread is the entity within a process that can
    be scheduled for execution.
  • All threads of a process share its virtual
    address space and system resources.
  • Each thread maintains
  • Exception handlers,
  • A scheduling priority,
  • Thread local storage,
  • A unique thread identifier,
  • And a set of structures the system will use to
    save the thread context until it is scheduled
    (thread's set of machine registers, the kernel
    stack, a thread environment block, and a user
    stack in the address space of the thread's
    process)

10
Process Spawning
  • We saw that processes can be spawned (executed)
    to parallelize the application, Win32 and MFC
    provides proper methods and functions to
    accomplish this
  • CreateProcess
  • ShellExecute
  • Demo code ...
  • But what happens if we want to do communication
    and share data between processes ? Why ?
  • IPC (Inter Process Communication)
  • Sockets, Pipes, Shared Memory
  • What about management of the processes ?
  • Killed by the system or killed by the user

11
Single vs. Multi Threads
12
Threads
  • Todays many operating systems (Windows, Linux,
    BSD, Solaris) support the multi-threading on
    various levels
  • Kernel Level
  • User Level
  • Hybrid
  • We will cover user level threads

13
Threads in Windows (MFC)
  • Thread Operations
  • Creating Threads
  • Suspending/Resuming Threads
  • Terminating/Exiting Threads
  • Synchronizing Execution of Multiple Threads

14
Threads in MFC
  • MFC distinguishes two types of threads
  • User-interface threads and worker threads.
  • User-interface threads are commonly used to
    handle user input and respond to events and
    messages generated by the user.
  • Worker threads are commonly used to complete
    tasks, such as recalculation, heavy-weight
    functions that do not require user input.

15
Worker Threads
  • A worker thread is commonly used to handle
    background tasks that the user should not have to
    wait for to continue using your application.
  • Tasks such as
  • Heavy-weight mathematical calculations
  • Background printing
  • Creating a worker thread is a relatively simple.
    Only two steps are required to get your thread
    running
  • Implementing the controlling function
  • Starting the thread.

16
Controlling Function
  • The controlling function defines the thread. When
    this function is entered, the thread starts, and
    when it exits, the thread terminates. This
    function should have the following prototype
  • UINT AnyControllingFunction ( LPVOID pParam )

17
SOME TYPES DEFINED IN WIN API
  • typedef int BOOL
  • typedef unsigned int UINT
  • typedef int INT
  • typedef char CHAR
  • typedef unsigned char BYTE
  • typedef void VOID
  • typedef float FLOAT
  • typedef FLOAT PFLOAT //pointer to
    float
  • typedef void LPVOID //pointer to void
  • typedef CHAR LPSTR
  • typedef const CHAR LPCSTR
  • typedef void PVOID
  • typedef PVOID HANDLE
  • typedef HANDLE HINSTANCE
  • typedef HANDLE HLOCAL
  • typedef char PSTR
  • ...

18
Controlling Function
  • UINT AnyControllingFunction ( LPVOID pParam )
  • The parameter is a single value.
  • It was passed to the constructor when the thread
    object was created.
  • The controlling function can interpret this value
    in any manner it chooses. It can be treated as
  • A scalar value
  • A pointer to a structure containing multiple
    parameters
  • It can be ignored.
  • If the parameter refers to a structure, the
    structure can be used not only to pass data from
    the caller to the thread, but also to pass data
    back from the thread to the caller.

19
Starting Worker Threads
  • You can derive a class if you need a special
    version of CWinThread, but it is not required for
    most simple worker threads. You can use
    CWinThread without modification
  • To start your worker thread call,
  • AfxBeginThread with providing the following
    information
  • The address of the controlling function
  • The parameter to be passed to the controlling
    function
  • pNewObject new MyObject
  • AfxBeginThread(MyControlFunc, pNewObject)

CWinThread AfxBeginThread( AFX_THREADPROC
pfnThreadProc, LPVOID pParam, int nPriority
THREAD_PRIORITY_NORMAL, UINT nStackSize
0, DWORD dwCreateFlags 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs NULL )
20
Worker Thread Example
  • include "stdafx.h"
  • include ltiostreamgt
  • using stdcout
  • using stdendl
  • UINT MyThreadFunc1 (LPVOID param)
  • while (true)
  • cout ltlt "Worker with no param" ltlt endl
  • Sleep (500)
  • return 0
  • UINT MyThreadFunc2 (LPVOID param)
  • int incoming (int) param
  • while (true)

21
Worker Thread Example
  • int main()
  • int parameter 1000
  • AfxBeginThread (MyThreadFunc1, NULL)
  • AfxBeginThread (MyThreadFunc2, parameter)
  • WaitForSingleObject(GetCurrentThread(),
    INFINITE)
  • return 0

22
Suspending and Resuming Thread Execution
  • Suspending a thread blocks the execution of the
    thread, when it is resumed it starts the
    execution from the point it is suspended
  • AfxBeginThread returns a pointer to CWinThread
    object, we can use that pointer to suspend and
    resume the thread
  • CWinThread curThread AfxBeginThread
    (MyThreadFunc, NULL)
  • .....
  • curThread-gtSuspendThread()
  • ....
  • curThread-gtResumeThread()
  • Sleep suspends the execution of the thread for a
    given amount of time
  • Sleep (100) // Suspends 100 milliseconds

23
User Interface Threads
  • User-interface threads have a message pump and
    process messages received from the system,
  • If we do not need to process any system messages
    worker threads are fine
  • Just implement a controlling function
  • And pass that function to AfxBeginThread
  • But if we need to process system messages such
    as,
  • User inputs
  • User interactions
  • Other OS messages (data on socket, and etc.)
  • We need to use User Interface Threads

24
User Interface Threads
  • For GUI applications the main thread of execution
    is provided by an object derived from CWinApp.
    CWinApp is derived from CWinThread.
  • Additional CWinThread objects allow multiple
    threads within a given application,
  • Basically our GUI applications are derived from
    CWinApp which constructs the primary thread of
    our application
  • class CThreadDemoApp public CWinApp
  • .....

25
User Interface Threads
  • In order to implement a multithreaded application
    we need to implement a class (or classes) which
    will derive from CWinThread
  • class CSocketThread public CWinThread
  • .....
  • We need to override the following methods
  • virtual BOOL InitInstance( )
  • Override to perform thread instance
    initialization.
  • virtual int ExitInstance( )
  • Override to clean up when your thread terminates.
  • virtual int Run( )
  • Controlling function for threads with a message
    pump. Override to customize the default message
    loop.

26
User Interface Threads
  • To create the thread we will use CreateThread
    method. This comes for free when we derive from
    CWinThread class.
  • When CreateThread is called from our application,
    CWinThread will call our derived InitInstance
    method and will leave the execution to our
    derived Run method

27
CWinThread Demo
  • class CSocketThread public CWinThread
  • public
  • CSocketThread(int pSocketId)m_SocketId(pSocketId
    )
  • virtual int Run()
  • virtual int ExitInstance()
  • virtual BOOL InitInstance()
  • private
  • int m_SocketId

28
CWinThread Demo
  • ...
  • int CSocketThreadRun()
  • while (true)
  • cout ltlt "Thread with Socket Id" ltlt m_SocketId
    ltlt endl
  • Sleep (1000)
  • return 0
  • ...
  • int main()
  • CSocketThread firstThread(10)
  • CSocketThread secondThread(20)
  • firstThread.CreateThread()

29
Thread Synchronization
  • Until now, we created threads and let them run.
    They do not share anything.
  • But suppose, you have a global data and some of
    the threads are reading that data and some of
    them are writing into it.
  • What happens when they access it at the same time
    ?
  • Hint what happened when both threads accessed the
    command line window to print out some info ?
  • (Undesirable and unpredictable results)

30
Thread Synchronization
  • Synchronizing resource access between threads is
    a common problem when writing multithreaded
    applications.
  • Having two or more threads simultaneously access
    the same data can lead to undesirable and
    unpredictable results.
  • For example, one thread could be updating the
    contents of a structure while another thread is
    reading the contents of the same structure. It is
    unknown what data the reading thread will
    receive the old data, the newly written data, or
    possibly a mixture of both.
  • MFC provides a number of synchronization and
    synchronization access classes to aid in solving
    this problem.

31
Thread Synchronization
  • Mutexes, Locks, Semaphores, and CriticalSections
    are used to prevent the data
  • CMutex
  • CSingleLock, CMultipleLock
  • CSemaphore
  • CCriticalSection
  • Basic idea here is to give the access of the data
    to only one thread at a time (which is also
    called thread-safe)
  • We will cover only one method shown above
    (CMutex)
  • The details of the MFC synchronization classes
    can be found on MSDN, but difference is the
    low-level structs used by MFC library (Faster or
    Slower thread context switches)

32
Thread Synchronization Demo
  • class CSynchThread public CWinThread
  • public
  • CSynchThread(CMutex pLock, int pSocketId)
  • ...
  • private
  • int m_SocketId
  • CMutex m_Lock
  • ...
  • CSynchThreadCSynchThread(CMutex pLock, int
    pSocketId)
  • m_SocketId(pSocketId), m_Lock(pLock)

33
Thread Synchronization Demo
  • int CSynchThreadRun()
  • while (true)
  • m_Lock-gtLock()
  • cout ltlt "Thread with Socket Id" ltlt m_SocketId
    ltlt endl
  • m_Lock-gtUnlock()
  • Sleep (1000)
  • return 0
  • int main()
  • CMutex mutex new CMutex()
  • CSynchThread firstThread(mutex, 10)
  • CSynchThread secondThread(mutex, 20)
  • firstThread.CreateThread()

34
What can go wrong ?
  • Debugging a multi-threaded application needs much
    more effort.
  • Too many switches between threads degrades the
    performance
  • Programmer needs to pay attention to problems
    such as,
  • Synchronization, Deadlocks, Starvation, and Race
    Conditions
  • Most of the data types and classes available for
    use are not thread safe

35
Deadlocks
  • Deadlocks occur when two or more threads (or
    processes) wait for each other to release a
    resource or waiting for resources in a circular
    chain,
  • Thread -1 Thread-2
  • LockResource(A) LockResource(A)
  • DoActionOn(A) DoActionOn(A)
  • ReleaseResource(A) //Forgetting to release

36
Deadlocks
  • Waiting for resources in circular chain,
  • Resources (A and B)
  • Threads (T1 and T2)

Resource-A is assigned to T2 and T2 waits for
Resource-B to accomplish its job and release
resources Resource-B is assigned to T1 and T1
waits for Resource-A to accomplish its job and
release resources
A
B
  • There are algorithms to detect, avoid and prevent
    deadlocks (Will be mentioned in OS Course)

37
Starvation
  • Starvation (or Resource Starvation)
  • From two or more of the threads, one thread is
    scheduled more often to execute but others are
    not
  • Faulty scheduling
  • One of the threads is unwilling to give up the
    resources for which the other threads are waiting
  • Famous Dining Philosophers Problem

38
Race Conditions
  • Race conditions arise when separate processes or
    threads depend on some shared state.
  • Example
  • Let us assume that two threads T1 and T2 each
    want to increment the value of a global integer
    by one.
  • Integer i 0
  • T1 reads the value of i from memory into a
    register 0
  • T1 increments the value of i in the register
    (register contents) 1 1
  • T1 stores the value of the register in memory 1
  • T2 reads the value of i from memory into a
    register 1
  • T2 increments the value of i in the register
    (register contents) 1 2
  • T2 stores the value of the register in memory 2
  • Integer i 2
  • In the case shown above, the final value of i is
    2, as expected.
  • However, if the two threads run simultaneously
    without locking or synchronization, the outcome
    of the operation could be wrong.

39
Race Conditions
  • Integer i 0
  • T1 reads the value of i from memory into a
    register 0
  • T2 reads the value of i from memory into a
    register 0
  • T1 increments the value of i in the register
    (register contents) 1 1
  • T2 increments the value of i in the register
    (register contents) 1 1
  • T1 stores the value of the register in memory 1
  • T2 stores the value of the register in memory 1
  • Integer i 1
  • The final value of i is 1 instead of the expected
    result of 2.
  • This occurs because the increment operations of
    the second case are non-atomic. Atomic operations
    are those that cannot be interrupted while
    accessing some resource, such as a memory
    location.

40
Threads for Windows
  • MFC Threads are not the only solution for
    threading on Windows,
  • POSIX Threads (or PThreads) Library
  • http//sourceware.org/pthreads-win32/
  • OpenThreads Library
  • http//openthreads.sourceforge.net/
  • Win32 Threads
  • http//msdn2.microsoft.com/en-us/library/
Write a Comment
User Comments (0)
About PowerShow.com