1+ #!/usr/bin/env python
2+ '''
3+ Created on Jul 24, 2013
4+
5+ @author: Kevin Evans
6+
7+ @summary: The following code sample takes a 1000 element array and updates each
8+ item in the array by setting them to 0 and then concurrent threads are
9+ created to each add 1 to each item in the array. The resulting array
10+ should contain 1000 items each set to 2. Access control to the array
11+ elements is controlled by the lock object. When the array updating is
12+ completed the resulting array is validated to contain the correct values
13+ for each item.
14+
15+ @note: An array was explicitly chosen over a python list to meet the requirement
16+ and to have better performance which is important with a multi-threaded environment.
17+
18+ @requires: Python 2.7.5
19+ @note: Tested on MacBook Pro Intel Core 2 Duo
20+ '''
21+
22+ import sys
23+ import logging
24+ import array
25+ import threading
26+ from itertools import repeat
27+
28+ class ThreadSafeArray (object ):
29+
30+ def __init__ (self ):
31+ #Logging needs to be setup to work in IDE console and command line
32+ self .logger = logging .getLogger ("ThreadSafeArray" )
33+ handler = logging .StreamHandler (sys .stdout )
34+ handler .setLevel (logging .DEBUG )
35+ self .logger .setLevel (logging .DEBUG )
36+ self .logger .addHandler (handler )
37+
38+ def arrayUpdater (self , array_for_updating , myLock ):
39+ for idx in range (len (array_for_updating )):
40+ myLock .acquire ()
41+ try :
42+ array_for_updating [idx ] += 1
43+ except :
44+ self .logger .error ("Could not acquire a lock" )
45+ finally :
46+ myLock .release ()
47+
48+
49+ def validateArray (self , array_for_checking ):
50+ badegg = 0
51+ for item in array_for_checking :
52+ if item != 2 :
53+ self .logger .error ("Didn't update the array properly" )
54+ badegg += 1
55+ if badegg > 0 :
56+ self .logger .error ("There were " + str (badegg ) + " items that were not updated properly" )
57+ else :
58+ self .logger .info ("All numbers in the array were updated properly" )
59+
60+
61+ def arrayThreader (self , ary ):
62+ #Acquire a lock object to control exclusive access to the array during an update
63+ myLock = threading .Lock ()
64+ #Acquire the thread objects
65+ t = threading .Thread (target = self .arrayUpdater , args = (ary , myLock ))
66+ w = threading .Thread (target = self .arrayUpdater , args = (ary , myLock ))
67+ #Start each thread so that they run concurrently through the array to update it
68+ t .start ()
69+ w .start ()
70+ #Wait for the threads to complete before moving forward
71+ t .join ()
72+ w .join ()
73+
74+ def run (self ):
75+ #Create the 1000 element array and use the repeat function to fill the array with zeros
76+ #Array type H is an unsigned short which has the best performance and space used.
77+ numberarray = array .array ('H' , repeat (0 , 1000 ))
78+ self .arrayThreader (numberarray )
79+ self .validateArray (numberarray )
80+
81+ def main ():
82+ arraybuilder = ThreadSafeArray ()
83+ arraybuilder .run ()
84+
85+ if __name__ == '__main__' :
86+ main ()
0 commit comments