Click here to Skip to main content
Licence 
First Posted 22 Oct 2003
Views 70,608
Downloads 725
Bookmarked 9 times

Multithreading VB Style: Locking A Shared Resource

By Xiangyang Liu 刘向阳 | 22 Oct 2003
A COM component to protect your shared resources in multithreaded applications.
3 votes, 8.3%
1

2

3
1 vote, 2.8%
4
32 votes, 88.9%
5
4.97/5 - 37 votes
3 removed
μ 4.63, σa 1.97 [?]

Introduction

In my previous article, I introduced a COM component that allows you to create new threads for background jobs in VB and ASP applications. What you need to do is put your code in a method of a COM object, not necessarily written with VB though, and then use the VBThread.dll to execute the said method from a new worker thread.

When writing code to be executed in multithreaded environment, you need to be careful with shared resources. For example, if multiple threads are allowed to update the same global variable simultaneously, it is likely to cause trouble sooner or later. And we do need to use shared resources in many occasions.

For example, one of our VB web applications loads some data from a remote database and keeps it in memory. When the data is requested, the application will use the data already in memory instead of going to the remote database to fetch it every time. This will reduce performance hit. Users typically do not change the data but they are allowed to do so, in which case the application will update data in both places: the memory and the database.

Of course, we don't want multiple users to update the data in memory simultaneously. What we need is a mechanism to lock the data before updating it and unlock it afterwards.

VBLockManager

This is a COM object contained in VBLock.dll written in VC++. The COM object is free threaded and all methods are thread-safe. You need to create only one instance of this object in your application and use it whenever you want. By the way, you can use it in C/C++ applications as well.

Suppose you have a shared global resource you want to protect in a multithreaded application. All you have to do is:

  1. Come up with a name string for a resource lock.
  2. Your code has to call the SetLock method using the name string as input, before accessing the said resource.
  3. After you are done with the said resource, call the ReleaseLock method to unlock it.

Here is a sample VB script file that does this:

...
' create the lock manager object somewhere in your code
dim oLockManager
set oLockManager = CreateObject("VBLockManager.1")
...
' assign the global resource a name string
dim sLockName
sLockName = "MyResource001"
...
' call the SetLock method before accessing the global resource
oLockManager.SetLock sLockName
' then access the global resource any way you want
...
' after you are done, call the ReleaseLock method so that
' other threads can access the global resource
oLockManager.ReleaseLock sLockName
...

Note that the SetLock and the ReleaseLock methods are different from their counterparts in C/C++ programs. Here are more descriptions of these two methods:

  • Both methods take a name string as the only argument.
  • The name string can be made up of (case-sensitive) letters and numbers.
  • A resource lock is global to the process and is identified by the name string only.
  • The SetLock method will block if the same lock is already set.
  • A thread will block itself if it makes two consecutive calls to SetLock using the same lock name string.
  • The ReleaseLock method can be called from a different thread to unlock a resource.
  • The ReleaseLock method can be called multiple times with no problem.

You need to add an extra call to ReleaseLock in your error-handling code in case the normal code execution is skipped.

As I said before, the VBLockManager object is free threaded and thread-safe, you can use the same instance anywhere in your code. But you can create and use multiple instances if you want to. There is also a TrySetLock method which works the same way as SetLock, except that it won't block. The TrySetLock method returns True if the lock is set successfully, otherwise it returns False.

Locking a Systemwide Resource

What if you have several different applications working together and you want to protect a system-wide resource so that only one process can access it at a time? VBLockManager provides methods SetLockPersist, ReleaseLockPersist and TryLockPersist, just for that purpose. These methods are the same as the ones described above, except that the locks are now global to the machine. Here is another VB script sample file demonstrating the use of these methods:

...
' create the lock manager object somewhere in your code
dim oLockManager
set oLockManager = CreateObject("VBLockManager.1")
...
' assign the global resource a name string
dim sLockName
sLockName = "MyGlobalResource002"
...
' call the SetLockPersist method before accessing the global resource
oLockManager.SetLockPersist sLockName"
' then access the global resource any way you want
...
' after you are done, call the ReleaseLockPersist method so
' that other threads can access the global resource
wscript.echo "Click OK when done"
oLockManager.ReleaseLockPersist sLockName
...

If you run two instances of the above code, you will see that the second instance will block until you click the OK button in the first instance.

Performance and other issues

I am sure the ideas described in this article is not new. As you may have guessed, I used the Win32 APIs to implement VBLockManager. For details, please look for Windows synchronization functions (such as InitializeCriticalSection, CreateMutex, etc.) in MSDN.

Since it takes a COM method call to lock or unlock a resource, the performance of this tool cannot be compared with code that does similar things in C/C++. Actually, performance was not my main concern when writing the tool. What I want is a tool that allows me to do multithreaded programming easily in VB and ASP applications. For the web applications I have tested, this tool does not seem to make anything noticeably slower. But, it all depends on what you want to do and how you do it. For example, if you use over a thousand locks in your application, the performance will drop quickly. If you use less than a hundred locks, the performance seems to be bearable.

The ReleaseAll method releases all in-process locks, the ReleaseAllPersist method releases all system-wide locks. The system-wide locks are stored in file VBLock.dat located in the same folder as VBLock.dll. This file is automatically created and updated. You can view it using notepad.exe. Deleting this file will be equivalent to releasing all system-wide locks.

And finally, you have to register VBLock.dll on your machine to make things work. :-)

Thank you for reading my articles.

Recent updates

  • 10/27/2003
    • Added the GetAllLocks method which returns a string that contains all in-memory locks.
    • Fixed a bug in the previous version with in-memory locks.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Xiangyang Liu 刘向阳



United States United States

Member


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralCrap! Crap! Crap! PinmemberTW6:07 24 Oct '03  
General... PinmemberXiangyang Liu7:42 24 Oct '03  
GeneralRe: Crap! Crap! Crap! PinmemberTW3:38 25 Oct '03  
GeneralAttitude PinmemberXiangyang Liu5:18 25 Oct '03  
GeneralRe: Attitude PinsussAnonymous5:04 10 Nov '03  
GeneralRe: Attitude PinsussAnonymous5:04 10 Nov '03  
GeneralRe: Crap! Crap! Crap! PinmemberNic Rowan3:16 7 Nov '03  
GeneralRe: Crap! Crap! Crap! PinmemberTW0:40 8 Nov '03  
GeneralAdvice PinmemberXiangyang Liu1:31 8 Nov '03  
GeneralRe: Advice PinmemberTW3:53 8 Nov '03  
GeneralRe: Advice PinmemberXiangyang Liu9:13 8 Nov '03  
GeneralRe: Advice PinsussAnonymous5:15 10 Nov '03  
GeneralRe: Advice PinmemberXiangyang Liu6:10 10 Nov '03  
GeneralWho TW is ... PinmemberXiangyang Liu1:17 8 Nov '03  
GeneralRe: Who TW is ... PinsussAnonymous5:17 10 Nov '03  
GeneralRe: Who TW is ... PinmemberXiangyang Liu6:02 10 Nov '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120209.1 | Last Updated 23 Oct 2003
Article Copyright 2003 by Xiangyang Liu 刘向阳
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid