Tuesday, May 11, 2010

Exercise 10: Concurrency and Threading demonstration in Python

1. Find definitions for eight terms and concepts used in threaded programming:
-Thread Synchronisation :
It is a method for preventing deadlock to occur when two or more threads trying to aquire the same resources at the same time by making the thread wait in the line while other thread is accessing the resources or making any change to it, preventing any collision between the them.

-Locks
A lock is a synchronization mechanism for enforcing limits on access to a resource in an environment where there are many threads of execution. Locks are one way of enforcing concurrency control policies.

-DeadLock
A Deadlock is a state in a computer system where two or more process are waiting for each other to finish thier task so that they can use the resource other process is using, but no one does finish the task. Therefore niether of the task can be completed and the resources are occupied as well.

-Semaphores
A semaphore is a protected variable or abstract data type that constiture a classic method of controlling access by several processes to a common resource in a parallel programming environment.

-Mutex (Mututal Exclusion)
It is an algorithm used in concurrent programming to avoid the simultaneous use of a common resource, such as a global variable, by pieces of computer code called critical sections.

-Thread
A thread results from a fork of a computer program into two or more concurrently running tasks. Multiple threads can exists within the same process and share resources such as memory, while different processes do not share these resources.

-Event
It is an action that is usually initiated outside the scope of a program and that is handled by a piece of code inside the program. Events are handled synchronous with the program flow. Main source of events are user who presses a key in the keyboard and hardware devices such as a timer.

-Waitable timer
A waitable time object is a synchronization object whose state is to signaled when the specified due time arrives. Manual-reset and synchronization are two types of waitable timer.

A simple demonstration of the threading module in Python (threaddemo.py) that uses both a lock and semaphore to control concurrency is by Ted Herman at the University of Iowa. The code and sample output below are worth a look. Report your findings.

threaddemo.py

# Create a bunch of threads, let each do some work, wait until all are done

import random

import threading

import time

# This takes about n/3 seconds to run (about n/3 clumps of tasks, times

# about 1 second per clump).

numtasks = 10

# no more than 3 of the 10 can run at once

# create a semaphore bounded up to 3

sema = threading.BoundedSemaphore(value=3)

# create a Read Lock

mutex = threading.RLock()

# running is a global variable to keep track

# of how many threads are running

running = 0

# the TestThread class is a subclass of threading.Thread,

# so it should supply the standard methods: run, ...

class TestThread(threading.Thread):

def run(self):

# tell python we access the global variable

global running

# introduce a random delay between 0 and 2

delay = random.random() * 2

print 'task', self.getName(), 'will run for', delay, 'sec'

# first, wait on the semaphore (limited to three threads)

sema.acquire()

# but only one of these three at a time should update

# the running variable

mutex.acquire()

running = running + 1

print running, 'tasks are running'

# release lock so another can update "running"

mutex.release()

# now sleep for a while (yawn....zzzzzzz)

time.sleep(delay)

# after wakeup, say we are done

print 'task', self.getName(), 'done'

# time to decrement "running"

mutex.acquire()

running = running - 1

print self.getName(), 'is finished.', running, 'tasks are running'

mutex.release()

# and finally, exit the group of three tasks

sema.release()

# main program: build and start all the threads

threads = []

# done in a function just for convenience

def starttasks():

for i in range(numtasks):

# show off Python's formatting feature

# by building a name for each thread

t = TestThread(name=""%i)

# add new name to list

threads.append(t)

# start thread

t.start()

starttasks()

print 'waiting for all tasks to complete'

# next statement waits for all threads to finish

for t in threads: t.join()

print 'all tasks done'


Here is the output window when you run the threaddemo.py script:

PythonWin 2.3.2 (#49, Nov 13 2003, 10:34:54) [MSC v.1200 32 bit (Intel)] on win32. Portions Copyright 1994-2001 Mark Hammond (mhammond@skippinet.com.au) - see

'Help/About PythonWin' for further copyright information.

>>> task will run for 0.120358615571 sec

1 tasks are running

task will run for 0.763990116379 sec

2 tasks are running

task will run for 0.207353153515 sec

3 tasks are running

task will run for 1.55806365714 sec

task will run for 0.776083733579 sec

task will run for 0.336440216469 sec

task will run for 1.55779500185 sec

task will run for 1.96896800957 sec

task will run for 1.57596561512 sec

task will run for 0.634052702735 sec

waiting for all tasks to complete

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

3 tasks are running

task done

is finished. 2 tasks are running

task done

is finished. 1 tasks are running

task done

is finished. 0 tasks are running

all tasks done


Here are the findings:

Here is my finding in A simple demonstration of the threading module:

  • Thread ID is only limited 10 ie form 0 to 9.
  • Variable delay that is used to control the processing time of thread (2 secs)
  • Variable sema is a threading semaphore and it is predefined running maximum 3 threads each time (sema = threading.BoundedSemaphore(value=3)).
  • Variable mutex is used to create the read lock for the thread (mutex = threading.RLock()).
  • Method acquire(), reads a wait flag(optional).This can be use to avoid blocking if the lock is held by someone else.
  • Variable running is used to count the total number of running threads.
  • when TestThread() gets executed, console will print out a thread ID and the expected running time. Then sema.acquire() checks the thread number whether is over 3 or not, if false, mutex creates a read lock for the waiting thread, and adds 1 to running.
  • When one of the 3 threads get fully executed , mutex releases the read lock of for that very thread and subtracts running by one.Then prints out that the task had been completed. No the one of the threading will be lock to be executed. These process continues for 10 circles or cycles.




  • Reference:

    What is Thread Synchronisation?, Retreived at May 8, 2010 from http://wiki.answers.com/Q/What_is_Thread_Synchronization

    Lock (Computer Science). Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Lock_(computer_science)

    DeadLock. Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Deadlock

    Semaphores. Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Semaphores

    Mututal Exclusion. Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Mutex

    Thread (Computer Science). Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Thread_(computer_science)

    Event (Computing). Wikipedia. 2010.Wikimedia Foundation, Inc. Retreived at May 8, 2010 from http://en.wikipedia.org/wiki/Event_(computing)

    Waitable Timer Objects- MSDN. Retreived at May 8, 2010 from


    No comments:

    Post a Comment