Getting Firmware versions of Sun ALOM, ILOM, ELOM and V20z/V40z systems

Thursday, December 31, 2009

This writing shows the commands to fetch the installed firmware versions on different kinds of Sun servers like ALOM, ILOM, ELOM and other IPMI based service processors (like v20z, v40z), getting the installed firmware versions may be useful for system administrators to upgrade/reinstall firmware manually from the server management console.

Note: You can get the firmware version displayed after logging into the management console (before getting into the management prompt), use the below commands to get more detailed information.

1. Getting installed firmware version on an ALOM systems
2. Getting installed firmware version on an ILOM systems
3. Getting installed firmware version on an ELOM systems
4. Getting installed firmware version on V20z/V40z IPMI based service processors

1. Getting installed firmware version on an ALOM systems (like Sun Fire V125, V210, V240, V245, V250, V440, V445, Netra 210, 240, 440)

Logon to the SC.

ALOM-v125-sp> showsc version -v
Advanced Lights Out Manager v1.6.9
SC Firmware version: 1.6.9
SC Bootmon version: 1.6.9

SC Bootmon Build Release: 01
SC bootmon checksum: B398A9C8
SC Bootmon built Dec 15 2008, 15:12:15

SC Build Release: 01
SC firmware checksum: 100B1E9D

SC firmware built Dec 15 2008, 15:12:46
SC firmware flashupdate DEC 27 2009, 09:34:14

SC System Memory Size: 8 MB

SC NVRAM Version = f

SC hardware type: 0

ALOM-v125-sp>

2. Getting installed firmware version on an ILOM systems (like Sun Fire X4100, X4100 M2, X4140, X4150, X4170, X4200, X4200 M2, X4250, X4270, X4600, X4600 M2, etc)

Logon to SP.

-> version
SP firmware 2.0.2.5
SP firmware build number: 32265
SP firmware date: Fri Apr 25 20:35:59 PDT 2008
SP filesystem version: 0.1.14

->

3. Getting installed firmware version on an ELOM systems (specific ones like Sun Fire X2100, X2100 M2, X2200, X2200 M2)

Logon to SP

/SP -> cd AgentInfo
/SP/AgentInfo

/SP/AgentInfo -> show

/SP/AgentInfo
Targets:
PEF
PET
SEL
console
mail
SNMP

Properties:
HWVersion = 0
FWVersion = 1.10
MacAddress = 00:12:42:70:34:D2
IpAddress = 192.168.1.2
NetMask = 255.255.255.0
Gateway = 192.168.1.1
DhcpConfigured = disable
DateTime = 12/31/2009-00:47:52
Name = SUNSP0016062248D2
Location =
Contact =
ConsoleTimeOut = 180
ConsoleMux = agent

Target Commands:
show
cd
set

/SP/AgentInfo ->

4. Getting installed firmware version on V20z/V40z IPMI based service processors

Logon to the SP.

localhost $ inventory get software
Name Revision Install Date Description
BIOS-V20z V1.33.5.2 Thu Sep 1 12:56:38 2005 Platform BIOS for V20z servers
Operator Panel V1.0.1.1 Fri Mar 25 20:00:57 2005 Operator Panel Firmware
PPCBoot V2.1.0.16 Thu Sep 1 12:45:57 2005 PPCBoot Software
SP Value-Add V2.3.0.11 Mon Apr 3 17:17:09 2006 SP Value-Add Software
SP Base V2.3.0.11 Mon Apr 3 17:17:09 2006 SP Base Software
localhost $ exit

Increasing SWAP space in Solaris

Increasing SWAP space is a common task especially when its a requirement to install and run a new application, though its quite trivial, a handy How-to doc is always useful and hence this one.

Assuming that you need to increase swap size in Solaris by 4GB, follow the below procedure.

1. Get the current swap size.

bash-3.00# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t2d0s1 31,65 8 16787912 16787912

2. Create a file of size 4G (say swapfile4G)

bash-3.00# mkfile 4g /swapfile4G
bash-3.00#

3. Add the specific file as swap

bash-3.00# swap -a /swapfile4G
bash-3.00#

4. Now the swap -l command should show the new file added as swap

bash-3.00# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t2d0s1 31,65 8 16787912 16787912
/swapfile4G - 8 8388600 8388600

Additionally to enable this swap file after system boot, add the following entry in /etc/vfstab.

/swapfile4G - - swap - no -

(Tab after each fields).

Updating Firmware on ILOM based Sun servers

Monday, December 28, 2009

In this post, we will see the steps to update firmware on ILOM based Sun servers, some of the ILOM based Sun systems are Sun Fire X4100, X4100 M2, X4140, X4150, X4170, X4200, X4200 M2, X4600, X4600 M2, etc, a complete list of supported platforms can be found here.

In the below example, we will be updating to the latest ILOM firmware available for the X4100/X4200 servers (version 2.0.2.5 which can be downloaded here) on an X4200 server.

Step 1: Copy the firmware image (say firmware_image_file) to be updated on /tftpboot directory on the server

Step 2: ssh to the ILOM console (SP)

Step 3: load -source tftp://<ServerIP>/<firmware_image_file>

After firmware update, the SP will reboot, login to the SP to verify the firmware update.

Example:

In the below example, IP address 192.168.1.1 corresponds to the server and the IP address 192.168.1.2 corresponds to the ILOM based SP (X4200 in this example).

(From the server 192.168.1.1)

bash-3.00# pwd
/firmware/X4200firmware/v2.0.2.5
bash-3.00# ls -l
total 28688
-rw-r--r-- 1 root root 14680064 Dec 28 07:52 ilom.X4100-2.0.2.5-r37165.ima

bash-3.00# cp ilom.X4100-2.0.2.5-r37165.ima /tftpboot/

bash-3.00# ls -l /tftpboot/ilom.X4100-2.0.2.5-r37165.ima
-rw-r--r-- 1 root root 14680064 Dec 28 07:54 /tftpboot/ilom.X4100-2.0.2.5-r37165.ima

bash-3.00# ssh -l root 192.168.1.2
Password:

Sun(TM) Integrated Lights Out Manager

Version 2.0.2.1

Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.

Warning: password is set to factory default.

-> version
SP firmware 2.0.2.1
SP firmware build number: 26075
SP firmware date: Wed Dec 26 05:28:55 EST 2007
SP filesystem version: 0.1.14

-> load -source tftp://192.168.1.1/ilom.X4100-2.0.2.5-r37165.ima

NOTE: A firmware upgrade will cause the server and ILOM to
be reset. It is recommended that a clean shutdown of
the server be done prior to the upgrade procedure.
An upgrade takes about 6 minutes to complete. ILOM
will enter a special mode to load new firmware. No
other tasks can be performed in ILOM until the
firmware upgrade is complete and ILOM is reset.

Are you sure you want to load the specified file (y/n)? y
Do you want to preserve the configuration (y/n)? y
...............................................................................................................
Preserving configuration. Please wait.
Done preserving configuration.


Firmware update is complete.
ILOM will now be restarted with the new firmware.

->
Broadcast message from root (pts/0) (Tue Dec 29 01:13:01 2009):

The system is going down for reboot NOW!
Connection to 192.168.1.2 closed by remote host.
Connection to 192.168.1.2 closed.

bash-3.00# ssh -l root 192.168.1.2
Password:

Sun(TM) Integrated Lights Out Manager

Version 2.0.2.5

Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.

Warning: password is set to factory default.

-> version
SP firmware 2.0.2.5
SP firmware build number: 37165
SP firmware date: Fri Sep 19 23:35:10 EDT 2008
SP filesystem version: 0.1.14

-
Related Post: Updating Firmware on ALOM based Sun servers.

Updating Firmware on ALOM based Sun servers

Sunday, December 27, 2009

Updating firmware is a routine system administration task and at times it helps if there is a quick reference to do it, in this blog we will see how to update an ALOM firmware on Sun systems.

Some of the ALOM based Sun servers are Sun Fire V125, V210, V240, V245, V250, V440, V445, Netra 210, 240, 440. We will see how to manually update the firmware on these systems.

In the below example, we will be updating to the latest ALOM firmware (version 1.6.9 which can be downloaded from the Sun website) on a Sun ALOM based hardware (an SF-V125 server used in the below example).

Step 1: telnet or ssh to the ALOM Management console (SC)

Step 2: Use the flashupdate command from the SC to fetch the firmware image from the server and update it.
(flashupdate -s <serverIP> -f <firmware_file_location_in_server> )

Step 3: After update is successful, use resetsc command to reset the SC, once the reset is complete, you can verify the latest firmware updated on the system by logging into the SC.

Example:

In the below example, IP address 192.168.1.1 corresponds to the server and the IP address 192.168.1.2 corresponds to the ALOM based SC.

(From the server 192.168.1.1)

bash-3.00# pwd
/firmware/ALOM-1.6.9
bash-3.00# ls
ALOM_1.6.9_fw_hw0.tar README alommainfw
Legal alombootfw copyright

bash-3.00# telnet 192.168.1.2
Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'.

Copyright 2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.


Sun(tm) Advanced Lights Out Manager 1.6.8 (v125-sp)

Please login: admin
Please Enter password: *****


v125-sp> flashupdate -s 192.168.1.1 -f /firmware/ALOM-1.6.9/alommainfw
Username: root
Password: **********

................................................................
Update complete. Reset device to use new image.
v125-sp>
SC Alert: SC firmware was reloaded

v125-sp> resetsc
Are you sure you want to reset the SC [y/n]? y
User Requested SC Shutdown
v125-sp> Connection to 192.168.1.2 closed by foreign host.
bash-3.00# telnet 192.168.1.2
Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'.

Copyright 2009 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.


Sun(tm) Advanced Lights Out Manager 1.6.9 (v125-sp)

Please login: admin
Please Enter password: *****


v125-sp>
)

Step 3: After update is successful, use resetsc command to reset the SC, once the reset is complete, you can verify the latest firmware updated on the system by logging into the SC.

Example:

In the below example, IP address 192.168.1.1 corresponds to the server and the IP address 192.168.1.2 corresponds to the ALOM based SC.

(From the server 192.168.1.1)

bash-3.00# pwd
/firmware/ALOM-1.6.9
bash-3.00# ls
ALOM_1.6.9_fw_hw0.tar README alommainfw
Legal alombootfw copyright

bash-3.00# telnet 192.168.1.2
Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'.

Copyright 2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.


Sun(tm) Advanced Lights Out Manager 1.6.8 (v125-sp)

Please login: admin
Please Enter password: *****


v125-sp> flashupdate -s 192.168.1.1 -f /firmware/ALOM-1.6.9/alommainfw
Username: root
Password: **********

................................................................
Update complete. Reset device to use new image.
v125-sp>
SC Alert: SC firmware was reloaded

v125-sp> resetsc
Are you sure you want to reset the SC [y/n]? y
User Requested SC Shutdown
v125-sp> Connection to 192.168.1.2 closed by foreign host.
bash-3.00# telnet 192.168.1.2
Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'.

Copyright 2009 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.


Sun(tm) Advanced Lights Out Manager 1.6.9 (v125-sp)

Please login: admin
Please Enter password: *****


v125-sp>
In future posts, we will see more useful information related to Sun systems/administration.

Creating ssh tunnel from Windows and Solaris

Wednesday, October 21, 2009

I was trying to find the easiest way to create an ssh tunnel from Windows to a Solaris box via an authenticated gateway server to access a secure web page in the target server, though there are many ways to do that, I found that the easiest one is to use command line.

Assume that a Host A wants to tunnel HTTPS traffic to host C via an authenticated Gateway server host C (where you have an account), then the following steps would be helpful.

Lets assume that the target's server IP address is 10.2.152.2 and the gateway IP is 10.2.152.1, and you want to access https://10.2.152.2:9443 from the source system.

Creating ssh tunnel from Solaris:

bash-3.00$ ssh -L 9443:10.2.152.2:9443 -X username@10.2.152.1
Password: ********
Last login: Wed Oct 21 20:03:26 2009 from system25
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
bash-3.00$

Now from a firefox browser if you type https://localhost:9443, the HTTPS traffic will be tunneled to https://10.2.152.2:9443.

Creating ssh tunnel from Windows:

Even though there are many ways to do it from Windows using putty, if you are an UNIX user who love command line, its almost similar to that of the above procedure.

1. Download putty (and cd to the directory where you cn find putty.exe).

2. C:\putty_install> putty -L 9443:10.2.152.2:9443 -X username@10.2.152.1
(A putty window opens)
Using username "username".
Using keyboard-interactive authentication.
Password: ********
Last login: Wed Oct 21 20:03:28 2009 from system25
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
bash-3.00$

Now https://localhost:9443 from Windows system will fetch https://10.2.152.2:9443.

Xstartup settings for accessing Solaris Desktop through VNC

Monday, October 19, 2009

Sometimes I find that if I start VNC Server with the default xstartup settings, I often end up landing on a terminal instead of the Solaris desktop (Java Desktop Session), for those of you having the same problem (can't access Solaris desktop through VNC), here is one possible solution which worked for me.

1. cd <HOME>/.vnc, where <HOME> is your home directory.

2. Edit xstartup file.

2.1. The settings which brought me the command line instead of Solaris JDS.
bash-3.00$ cat xstartup
#!/bin/sh
PATH=:/pkg/X11/bin:/import/pkg/X11/bin
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
twm &
bash-3.00$
2.2 Replace the contents of xstartup to the one shown below (I commented out some lines, but you may retain these)
bash-3.00$ cat xstartup
#!/bin/sh
#[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
#xsetroot -solid grey
#vncconfig -iconic &
#xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
gnome-session &
bash-3.00$
2.3 Restart VNC Server

Kill the VNC Server process with the old xstartup settings (ps -ef | grep Xvnc, then use kill -9 <Xvnc-pid>), remove
<HOME>/.vnc/passwd, start another VNC Server using the vncserver command.

Thread Programming in C, Java and Python with mutual exclusion/synchronization/locks

Wednesday, July 29, 2009

The concept of thread programming at times intimidates the programmers, this is due to the way its been implemented with different constructs, but the purpose is the same, to efficiently use system resources with concurrent execution, with that being said, this simple writing gives you an introduction to programming with threads and how it affects program execution with and without the use of locks or mutual exclusion or synchronization, whatever you may call it, lets start.

The below three programs are similar, they use threads without and with locks, there will be four threads which would increment a shared counter variable (or a global variable), sleep for a second and tries to print the incremented value, we will see the case without the use of the locks to see how the processor switches between threads and the effect of using locks to synchronize code so that only one thread can access a portion of the synchronized block and runs into completion.

As always the languages used are C, java and python, lets start with C language for change (Note: gcc compiler is used here).

1. Thread Programming in C with and without mutual exclusion
2. Thread Programming in java with and without synchronization
3. Thread Progamming in Python with and without synchronization

1. Thread Programming in C with and without mutual exclusion

Listing 1.1 threads.c (Threads without mutual exclusion)



1.  /* threads.c
2.     Example of multithreaded programming in C without mutual exclusion/locks
3.     Author: S.Prasanna
4.  */
5.
6.  #include <pthread.h>
7.  #include <stdio.h>
8.
9.  int count = 0;
10.
11. void* run_thread()
12. {
13.    pthread_t thread_id = pthread_self();
14.    printf("Thread %u: Current value of count = %d\n", thread_id, count);
15.    printf("Thread %u incrementing count ...\n");
16.    count++;
17.    sleep(1);
18.    printf("Value of count after incremented by thread %u = %d\n", thread_id, count);
19.    pthread_exit(NULL);
20. }
21.
22. int main (int argc, char *argv[])
23. {
24.    pthread_t thread_array[4];
25.    int i = 0, ret, thread_num = 4;
26.
27.    for (i = 0; i < thread_num; i++) {
28.       if ((ret = pthread_create(&thread_array[i], NULL, run_thread, NULL)) == -1) {
29.          printf("Thread creation failed with return code: %d", ret);
30.          exit(ret);
31.       }
32.    }
33.    pthread_exit(NULL);
34. }
Output:

Thread 2: Current value of count = 0
Thread 2 incrementing count ...
Thread 3: Current value of count = 1
Thread 3 incrementing count ...
Thread 4: Current value of count = 2
Thread 4 incrementing count ...
Thread 5: Current value of count = 2
Thread 5 incrementing count ...
Value of count after incremented by thread 4 = 4
Value of count after incremented by thread 3 = 4
Value of count after incremented by thread 5 = 4
Value of count after incremented by thread 2 = 4

Explanation:

In the above code, we use Pthreads interface for implementing the thread functionality in C, although I won't be going through the Pthread methods here, the above code creates four threads (line 27 - 31) which invokes the function run_thread function whose return type is a pointer to void (line 11) where all threads increment the global count value (line 16), sleeps for a second and prints the value of count after its incremented by that thread (lines 11 - 20), since context switch occurs when threads sleep, the other threads increment the value by the time a thread sleeps and so on, as a result the threads couldn't print the value of count correctly after its incremented by them, this problem can be solved using mutual exclusion construct as shown below.

Listing 1.2 threads_lock.c (Threads with mutual exclusion)

1.  /* threads_lock.c
2.     Example of multithreaded programming in C with mutual exclusion/locks
3.     Author: S.Prasanna
4.  */
5.
6.  #include <pthread.h>
7.  #include <stdio.h>
8.
9.  int count = 0;
10. pthread_mutex_t thread_lock;
11.
12. void* run_thread()
13. {
14.    pthread_mutex_lock(&thread_lock);
15.    pthread_t thread_id = pthread_self();
16.    printf("Thread %u: Current value of count = %d\n", thread_id, count);
17.    printf("Thread %u incrementing count ...\n");
18.    count++;
19.    sleep(1);
20.    printf("Value of count after incremented by thread %u = %d\n", thread_id, count);
21.    pthread_mutex_unlock(&thread_lock);
22.    pthread_exit(NULL);
23. }
24.
25. int main (int argc, char *argv[])
26. {
27.    pthread_t thread_array[4];
28.    int i = 0, ret, thread_num = 4;
29.
30.    for (i = 0; i < thread_num; i++) {
31.       if ((ret = pthread_create(&thread_array[i], NULL, run_thread, NULL)) == -1) {
32.          printf("Thread creation failed with return code: %d", ret);
33.          exit(ret);
34.       }
35.    }
36.    pthread_exit(NULL);
37. }
38.
Output:

Thread 2: Current value of count = 0
Thread 2 incrementing count ...
Value of count after incremented by thread 2 = 1
Thread 5: Current value of count = 1
Thread 5 incrementing count ...
Value of count after incremented by thread 5 = 2
Thread 4: Current value of count = 2
Thread 4 incrementing count ...
Value of count after incremented by thread 4 = 3
Thread 3: Current value of count = 3
Thread 3 incrementing count ...
Value of count after incremented by thread 3 = 4

Explanation:

The above code is similar to the Listing 1.1 with mutual exclusion construct to ensure exclusive access to the portion of code which would be executed only by a single thread to completion without context switching, a thread acquires a lock with the call to pthread_mutex_lock (line 14) and releases the lock using pthread_mutex_unlock (line 21), both methods take a pthread_mutex_t member thread_lock on which the lock is acquired or released (line 10), thus mutual exclusion ensures that all atomic operations run to completion without context switching.

2. Thread Programming in java with and without synchronization

Listing 2.1 Counter.java (Threads without synchronization)
1.  /*
2.   * An example of threads without lock (synchronized block)
3.   * Author: S.Prasanna
4.   *
5.   */
6.
7.  public class Counter implements Runnable {
8.
9.      int count = 0;
10.
11.     public Counter() {  
12.     }
13.
14.     public void run() {
15.         System.out.println(Thread.currentThread().getName() + ": " + "Current Value of count = " + count);
16.         System.out.println(Thread.currentThread().getName() + " increments count....");
17.         count ++;
18.         try {
19.             Thread.currentThread().sleep(1000);
20.         } catch (InterruptedException e) {
21.             System.out.println("Thread " + Thread.currentThread().getName() + "interrupted.");
22.         }
23.         System.out.println("Value of count after incremented by thread "
24.         + Thread.currentThread().getName() + " = " + count);
25.     }
26.
27.     public static void main(String args[]) {
28.         Counter c = new Counter();
29.   
30.         Thread t1 = new Thread(c);
31.         Thread t2 = new Thread(c);
32.         Thread t3 = new Thread(c);
33.         Thread t4 = new Thread(c);
34.   
35.         t1.setName("Thread 1");
36.         t2.setName("Thread 2");
37.         t3.setName("Thread 3");
38.         t4.setName("Thread 4");
39.   
40.         t1.start();
41.         t2.start();
42.         t3.start();
43.         t4.start();
44.   
45.         try {
46.             t1.join();
47.             t2.join();
48.             t3.join();
49.             t4.join();
50.         }
51.         catch (InterruptedException e) {
52.             System.out.println("Main thread Interrupted .....");
53.         }
54.   
55.         System.out.println("Main thread exits.....");
56.     }
57. }
58.
Output:

C:\>java Counter
Thread 1: Current Value of count = 0
Thread 1 increments count....
Thread 2: Current Value of count = 1
Thread 2 increments count....
Thread 3: Current Value of count = 2
Thread 3 increments count....
Thread 4: Current Value of count = 3
Thread 4 increments count....
Value of count after incremented by thread Thread 1 = 4
Value of count after incremented by thread Thread 2 = 4
Value of count after incremented by thread Thread 3 = 4
Value of count after incremented by thread Thread 4 = 4
Main thread exits.....

Explanation:

The main method creates four threads (lines 30 - 33) created by extending the Runnable interface which increments the Counter's instance variable count (line 17), sleeps for a second and prints the incremented value (lines 14 - 25), since context switch occurs when a thread sleeps, other threads increment the count value by the time a thread sleeps and when the sleeping threads resumes execution, it read a wrong count value, this can be fixed with the synchronized construct as seen in Listing 2.2.

Listing 2.2 Counter_locks.java (Threads with synchronization)

1.  /*
2.   * An example of threads without lock (synchronized block)
3.   * Author: S.Prasanna
4.   *
5.   */
6.
7.  public class Counter_locks implements Runnable {
8.
9.      int count = 0;
10.
11.     public Counter_locks() {  
12.     }
13.
14.     public synchronized void run() {
15.         System.out.println(Thread.currentThread().getName() + ": " + "Current Value of count = " + count);
16.         System.out.println(Thread.currentThread().getName() + " increments count....");
17.         count ++;
18.         try {
19.             Thread.currentThread().sleep(1000);
20.         } catch (InterruptedException e) {
21.             System.out.println("Thread " + Thread.currentThread().getName() + "interrupted.");
22.         }
23.         System.out.println("Value of count after incremented by thread "
24.         + Thread.currentThread().getName() + " = " + count);
25.     }
26.
27.     public static void main(String args[]) {
28.         Counter_locks c = new Counter_locks();
29.   
30.         Thread t1 = new Thread(c);
31.         Thread t2 = new Thread(c);
32.         Thread t3 = new Thread(c);
33.         Thread t4 = new Thread(c);
34.   
35.         t1.setName("Thread 1");
36.         t2.setName("Thread 2");
37.         t3.setName("Thread 3");
38.         t4.setName("Thread 4");
39.   
40.         t1.start();
41.         t2.start();
42.         t3.start();
43.         t4.start();
44.   
45.         try {
46.             t1.join();
47.             t2.join();
48.             t3.join();
49.             t4.join();
50.         }
51.         catch (InterruptedException e) {
52.             System.out.println("Main thread Interrupted .....");
53.         }
54.   
55.         System.out.println("Main thread exits.....");
56.     }
57. }
58.
Output:

C:\>java Counter_locks
Thread 1: Current Value of count = 0
Thread 1 increments count....
Value of count after incremented by thread Thread 1 = 1
Thread 4: Current Value of count = 1
Thread 4 increments count....
Value of count after incremented by thread Thread 4 = 2
Thread 3: Current Value of count = 2
Thread 3 increments count....
Value of count after incremented by thread Thread 3 = 3
Thread 2: Current Value of count = 3
Thread 2 increments count....
Value of count after incremented by thread Thread 2 = 4
Main thread exits.....

Explanation:


Listing 2.2
differs from Listing 2.1 in a single line, it synchronizes the run method (line 14) executed by threads to ensure that only a single thread can access the synchronized block at any point of time, therefore a thread runs through the synchronized block of code without context switching, resulting in printing the correct count value after it increments it.

3. Thread Programming in python with and without synchronization


For a comprehensive introduction on python thread programming, do read my article on Introduction to python thread programming, I am listing that portion of the code here for the sake of completeness.


Listing 3.1 pythtreads.py (Threads without locks)

1.  #
2.  # Invoking multiple threads from python without locking mechanism
3.  # pythreads.py
4.  # Author: S.Prasanna
5.  #
6.
7.  import thread
8.  import threading
9.  import time
10.
11. def run_thread (threadname, sleeptime):
12.     """This is the thread function to be invoked."""
13.
14.     global threadcount, activethreads
15.
16.     print "%s: Current value of threadcount %s" % (threadname, threadcount)
17.     print "%s incrementing threadcount" % (threadname)
18.     threadcount = threadcount + 1
19.     time.sleep(sleeptime)
20.     print "Value of threadcount after incremented by %s = %s" % (threadname, threadcount)
21.     activethreads = activethreads - 1
22.     print "%s exiting...." % (threadname)
23.   
24. if __name__ == "__main__":
25.
26.     threadcount=0
27.     activethreads = 4
28.
29.     thread.start_new_thread(run_thread, ("Thread1", 1))
30.     thread.start_new_thread(run_thread, ("Thread2", 1))
31.     thread.start_new_thread(run_thread, ("Thread3", 1))
32.     thread.start_new_thread(run_thread, ("Thread4", 1))
33.
34.     while activethreads > 0:
35.         pass
36.
Output:

C:\>python pythreads.py
Thread1: Current value of threadcount 0
Thread1 incrementing threadcount
Thread2: Current value of threadcount 1
Thread2 incrementing threadcount
Thread3: Current value of threadcount 2
Thread3 incrementing threadcount
Thread4: Current value of threadcount 3
Thread4 incrementing threadcount
Value of threadcount after incremented by Thread1 = 4
Thread1 exiting....
Value of threadcount after incremented by Thread2 = 4
Thread2 exiting....
Value of threadcount after incremented by Thread3 = 4
Thread3 exiting....
Value of threadcount after incremented by Thread4 = 4
Thread4 exiting....

Explanation:

Thread programming python is quite simple to say the least, the main creates four threads using the thread module's start_new_thread() method (lines 29 - 32), each invokes the run_thread() (line 11) method which increments a shared variable count, sleeps for a second and prints the incremented value, since no lock mechanism is used ensure exclusive access, context switch occurs when the threads sleep as a result they read a wrong value upon resuming (after its incremented by other threads), the solution, Listing 3.2 with locks.

Listing 3.2 pythtreads_lock.py (Threads with locks)

1.  #
2.  # Invoking multiple threads from python with locks
3.  # pythreads_lock.py
4.  # Author: S.Prasanna
5.  #
6.
7.  import thread
8.  import threading
9.  import time
10.
11. def run_thread (threadname, sleeptime):
12.     """This is the thread function to be invoked."""
13.
14.     global threadcount, activethreads, threadlock
15.
16.     threadlock.acquire()
17.
18.     print "%s: Current value of threadcount %s" % (threadname, threadcount)
19.     print "%s incrementing threadcount" % (threadname)
20.     threadcount = threadcount + 1
21.     time.sleep(sleeptime)
22.     print "Value of threadcount after incremented by %s = %s" % (threadname, threadcount)
23.     activethreads = activethreads - 1
24.     print "%s exiting...." % (threadname)
25.
26.     threadlock.release()
27.
28. if __name__ == "__main__":
29.
30.     threadcount=0
31.     activethreads = 4
32.     threadlock = thread.allocate_lock()
33.
34.     thread.start_new_thread(run_thread, ("Thread1", 1))
35.     thread.start_new_thread(run_thread, ("Thread2", 1))
36.     thread.start_new_thread(run_thread, ("Thread3", 1))
37.     thread.start_new_thread(run_thread, ("Thread4", 1))
38.
39.     while activethreads > 0:
40.         pass
41.
Output:

C:\>python pythreads_lock.py
Thread1: Current value of threadcount 0
Thread1 incrementing threadcount
Value of threadcount after incremented by Thread1 = 1
Thread1 exiting....
Thread2: Current value of threadcount 1
Thread2 incrementing threadcount
Value of threadcount after incremented by Thread2 = 2
Thread2 exiting....
Thread3: Current value of threadcount 2
Thread3 incrementing threadcount
Value of threadcount after incremented by Thread3 = 3
Thread3 exiting....
Thread4: Current value of threadcount 3
Thread4 incrementing threadcount
Value of threadcount after incremented by Thread4 = 4
Thread4 exiting....

Explanation:

The thread.allocate_lock() (line 32) method creates a lock object which a thread acquires using its acquire() method (line 16) before performing an atomic operation (lines 17 - 25), releases the lock using the release() method (line 26) so that other threads can access the mutually exclusive code block.


Copyright © 2016 Prasanna Seshadri, www.prasannatech.net, All Rights Reserved.
No part of the content or this site may be reproduced without prior written permission of the author.