The Trouble with Threads - PowerPoint PPT Presentation

1 / 15
About This Presentation
Title:

The Trouble with Threads

Description:

Programming language level construct for mutual exclusion ... Monitor type construct easier for programmers to use ... or similar constructs. Trickier to ... – PowerPoint PPT presentation

Number of Views:38
Avg rating:3.0/5.0
Slides: 16
Provided by: michae64
Category:

less

Transcript and Presenter's Notes

Title: The Trouble with Threads


1
The Trouble with Threads
  • They access shared data (almost always)
  • They break in on each other at totally
    unpredictable times
  • Result bad behaviour, such as in
    Multiprogramming Java 1 4, which behaves
    unpredictably and not as might be expected.
  • Cure we cant avoid sharing data, but maybe we
    can prevent break-ins.
    (locks come into this somewhere)
  • Want to make some sections of code atomic, i.e.
    cant break into these are known as critical
    sections, only one thread can be in a CS at a
    time, others must wait.
  • Want mutual exclusion if one thread is
    working on some shared data, make other threads
    wait to get at it until first thread is done with
    it put processing of shared data in a critical
    section.
  • Need a kind of lock if open, a thread can
    pass through, setting the lock to prevent other
    threads coming through after it - these then have
    to wait until the thread that has the lock
    releases it again.
  • In Java, each object has a lock, which a thread
    can try to acquire by using the keyword
    synchronized this can be used to correct the
    behaviour of Multiprogramming Java 1 4.
  • Well have a quick look at Java later, but first,
    some thoughts on locks

2
The Trouble with Locks 1
  • Whats to stop two threads trying to set the lock
    at the same time?
  • This can actually happen in a multiprocessor
    system. With a single processor, both threads
    cant be active simultaneously, but one might be
    just setting the lock when the other gets in to
    set it, and both end up thinking they can go
    ahead lost update type of problem again.
  • Need to make the lock operation itself atomic.
    Trickier than it seems usually depends on some
    atomic hardware feature, though pure software
    solutions do exist (cf Dekkers Algorithm or
    Petersons Algorithm)
  • When a thread tries to execute a locked section
    of code, it must wait, but how?
  • The dissappointed thread might just keep trying,
    checking the lock over and until it is open and
    the thread can get it. If the lock gets set for
    only a very brief time this busy waiting is
    o.k., but otherwise it is very wasteful of
    machine cycles, usually best avoided.
  • Instead, suspend the dissappointed thread and put
    it on a queue or set of threads waiting for this
    lock. Now when lock is released, need to be able
    to resume one of the waiting threads.
  • (So there is more to Javas synchronized than
    meets the eye)

3
The Trouble with Locks 2
  • Making the lock operation atomic
  • At the lowest level, i.e. the hardware, two main
    approachs
  • Turn off interrupts,
  • if lock not set then set it
  • else prepare to wait,
  • turn on interrupts
  • Often used on single processor systems since
    interrupts are needed to break into a running
    thread, nothing can break into the thread that
    turns off interrupts. N.B. should only turn off
    interrupts for very short time.
  • But wont work on multiprocessor system, as
    threads keep running on other processors.
  • 2. register set, exchange(register,lock),
    if (registerset) wait
  • Requires an atomic machine instruction that can
    exchange data in memory with data in a register.
    If the lock was already set, wait, otherwise you
    have set it, proceed. Works for multiprocessor.
  • These are used to build more convenient higher
    level constructs, such as semaphores,
    monitors and message passing

4
Semaphores
  • Low level mechanism for mutual exclusion
  • Typically provided at the operating system level
  • Due to Dijkstra, who based it on train signals
    (i.e. semaphores)
  • Basically,
  • an integer variable, a queue for waiting
    threads,
  • and two operations, wait and signal,
    bothatomic
  • Used
  • init initialise the variable to something gt 0
    (often 0)
  • wait if (--variable lt 0)
  • suspend thread and put on this semaphores
    queue
  • signal if (variable lt 0)
  • take a suspended process from the
    semaphores queue and put it on ready to
    run queue used by operating system.
  • Widely used in low level programming care
    needed, as easy to get mixed up if many
    semaphores and lots of code

5
Monitors
  • Programming language level construct for mutual
    exclusion
  • Developed by Tony Hoare, also Per Brinch Hansen
  • N.B. totally different to batch job monitor
    mentioned earlier.
  • Easier to use, fewer programming errors, than
    semaphores.
  • Compiler may implement it using operating system
    semaphore calls.
  • Basically
  • very like an object - data and methods - but
    with a lock and a queue for waiting threads
  • thread must acquire the lock in order to use any
    part of monitor, so only one thread using any
    part of monitor at a time
  • lock is re-opened when thread leaves monitor
  • lock also re-opened when thread in monitor waits
    on a condition also need a way to keep track of
    threads that are waiting on a condition
  • need to be able to signal waiting threads when
    condition becomes true, so that one of them will
    again try to re-obtain the lock, continue in the
    monitor from where it did the wait
  • Modified monitor structure is used in Java to
    support multithreading

6
Locking hierarchy
  • The locking needed to support use of
    multithreading comes in various guises, typically
  • High Level Language Level
  • Monitor type construct easier for programmers
    to use
  • Compiler may implement monitor by generating
    calls to operating system semaphore functions
  • Programmers may also be able to use semaphores
    directly
  • Operating System Level
  • Message passing (distributed operating systems)
  • Semaphores or similar constructs
  • Trickier to program with than monitors
  • Implementation usually based on atomic hardware
    operations
  • Computer Hardware
  • Disable interrupts (single processor system)
  • Atomic exchange or test and set machine
    instructions

7
Java Threads - Locking
  • Quick summary
  • Based on monitor concept, but not exactly the
    same
  • Every object has a lock, a set to hold threads
    waiting on the lock, and a set to hold threads
    that have called wait().
  • A method can be made a critical section by using
    synchronized this obtains the lock on the
    object on method entry, releases it on exit, in
    between a thread that tries to use a synchronized
    method of the object must wait.
  • Lock can be obtained instead by using
    synchronized(myobject) instructions - now the
    instructions cannot be broken into by another
    thread which also uses synchronized(myobject)
    N.B. if another
    thread does not use synchronized(myobject), it
    can get in at any time, since it does not try to
    acquire the myobject lock.
  • Once a thread has acquired a lock it can acquire
    it again many times, e.g. by nested calls to
    synchronised methods in the same class. The lock
    must be released as many times as it was gained
    to unlock the object.
  • wait() causes thread to release the lock, become
    suspended in wait() set.
  • notify() causes thread in wait() set to be moved
    to the waiting on lock set. Method that used
    notify() runs on to completion. Moved thread will
    get the object lock again sometime it then
    continues from where it called wait().

8
Synchronising threads 1
  • As weve seen, threads use shared data
  • Quite often they do so in a way that requires
    synchronisation
  • e.g. one thread must wait to use data until
    another thread has set it up
  • Typical tools for synchronisation include
    mailboxes, queues, and message passing. These are
    provided by the operating system. While their
    implementation in the operating system involves
    careful use of appropriate locks, the user does
    not need to get involved with such tricky
    details.
  • A thread that tries to empty a mailbox is
    suspended if it is empty, and waits until some
    other thread puts something in the mailpox. It
    then empties the mailbox and continues.
  • With queues, various threads may post data, i.e.
    put it on the queue, while others pend on the
    queue, i.e. try to get something off the queue,
    waiting for it to be there if the queue is empty.
  • Queues are very useful. An example is a print
    queue the print thread takes the next file to
    be printed from the queue and prints it if
    there is nothing to be printed the thread is
    suspended. Any thread that needs to get a file
    printed puts it on the queue if the queue was
    empty that wakes up the print thread.

9
Synchronising threads 2
  • Message passing - threads can achieve mutual
    exclusion and/or synchronise using messages which
    they send(destination,message) and
    receive(source,message)
  • Both sending and receiving can be blocking or
    non-blocking
  • Blocking send, Blocking receive both sender and
    receiver threads are suspended until the message
    is received sometimes called a rendezvous
  • Non-blocking send, blocking receive the sender
    keeps going without waiting to ensure the message
    has arrived. Behaves like a queue. Probably most
    useful version.
  • Non-blocking send, non-blocking receive both
    sender and receiver keep going.
  • Blocking send, non-blocking receive not much
    used
  • Various addressing schemes are used for
    identifying the source and the destination.
  • Various approaches to message priority, and to
    lost messages.
  • Concept can be scaled up to synchronising
    threads/processes on different machines in a
    distributed environment.

10
Deadlock 1
  • Get the mutual exclusion or synchronisation
    wrong, result can be deadlock
  • Two (or more) threads are suspended, each waiting
    on a resource held by the other as neither can
    proceed they never get to hand back the resources
    they hold, so remain suspended forever- deadlock
  • e.g.
  • Thread 1 Thread 2
  • get resource A get resource B
  • get resource B get resource A
  • return resource A return resource B
  • return resource B return resource A
  • Most of the time, the above threads will run
    fine.
  • But when (it will happen) Thread 2 breaks in
    after Thread 1 has got A and before it gets B,
    Thread 2 will get B but be suspended when it
    tries to get A. Thread 1 can now resume, but will
    be suspended when it tries to get B. Both are now
    suspended, each waiting on the other to do
    something deadlock

11
Deadlock 2
  • Deadlock can involve many more than two threads,
    and the chain of requirements can be quite long,
    making deadlock harder to detect. See the Dining
    Philosophers problem for a standard example.
  • All thats needed for deadlock is
  • Resources cannot be shared, i.e. be in use by
    two threads at one time
  • Threads keep resources until finished with them
    they cannot be forced to give them back earlier
    no pre-emption
  • Threads acquire resources piecemeal as they need
    them they dont e.g. acquire them all at the
    start, on an all or nothing basis
  • With these conditions satisfied, we can now have
  • A circular pattern of threads suspended waiting
    for resources held by other suspended threads -
    deadlock

12
Deadlock 3
  • Dealing with deadlock is tricky
  • Can prevent
  • Force thread to grab all resources at start
    wasteful, as most of the time they are not in use
  • or Insist threads get resources in a certain
    order, e.g. always A before B
  • or Pre-empt by grabbing back already allocate
    resources may need to start grabbed-from thread
    over again, maybe get trapped in cycle
  • Can avoid
  • Check when each result is allocated that
    deadlock cant result, refuse allocation if it
    can. Bankers algorithm.
  • Can detect
  • If deadlock only happens very rarely, may be
    feasible to simply let it happen, detect it, and
    restart the system.
  • All of the above approaches have problems.
  • Dealing with Deadlock is a serious problem for
    operating systems, which must manage perhaps
    hundreds of threads sharing many resources.

13
Deadlock in Java (1)
  • class Resource
  • String name
  • public Resource(String name)
  • this.name name

14
Deadlock in Java (2)
  • class Mythread extends Thread
  • Resource first,second
  • public Mythread(Resource usefirst, Resource
    usesecond)
  • first usefirst
  • second usesecond
  • public void run()
  • while (true)
  • System.out.println(Thread.currentThread().ge
    tName())
  • synchronized(first)
  • System.out.println(first.name)
  • synchronized(second)
  • System.out.println(second.name)

15
Deadlock in Java (3)
  • class Mydeadlock
  • public static void main(String args)
  • Resource chalk new Resource(Chalk")
  • Resource duster new Resource(Duster")
  • Mythread t1 new Mythread(chalk,duster)
  • Mythread t2 new Mythread(duster,chalk)
  • t1.start()
  • t2.start()
Write a Comment
User Comments (0)
About PowerShow.com