How synchronization works

Synchronization involves sharing a single CPU among multiple tasks (or threads) in a way designed to minimize the time required to switch threads. On a thread-enabled server, agents take turns performing their tasks, which saves time and gives the illusion of the tasks occuring at the same time.

This sample agent, Comm1, run at the same time as an identical one named Comm2, illustrates how you can use code locks to synchronize agent execution.

Run concurrently, these agents create a named lock called "Update," then:

  • If Comm1 is the first agent to start execution, it gets the lock; the second (Comm2) must wait for Comm1 to release it before starting. Comm1 outputs a message that it has the lock and provides the reference count.
  • As soon as Comm1 is done with the lock, it releases it and Comm2 takes it. Comm1 tries to obtain the lock again, but now must wait until Comm2 is done with it. Comm2 outputs a message that it now has the lock and reports the reference count again.
  • As soon as Comm2 is done with the lock, it releases it and Comm1 takes it.

The process repeats for the duration of "For loop," in this case, 5 iterations.

'Comm1: 
Option   Public
' Remove the following line if you do not have a
' resource library defined. 
Use "ThreadsLib"
Sub Initialize
   Dim lockName As String
   Dim lockID As Integer, refcnt As Integer
   Dim gotLock As Variant,  releaseLock As Variant, _
    deleteLock As Variant
   On Error Goto syn_error
   ' Provide some unique name here to distinguish the agents.
   ID = "Comm1  tuvwx:5706 " 
   Msgbox  ID & "Started"
   lockName = "Update"
   On Error Goto syn_error
   ' Create the lock
   lockID = Createlock(uName)
   If (lockID <> -1) Then
      Msgbox ID & "Created lock: " & lockID
   End If
   ' Put agent to sleep for a second.  
   ' This gives the second agent time to start.
   Sleep 1
   For x = 1 To 5
      ' Attempt to get the lock and report the outcome
      ' as well as the reference count
      gotLock = CodeLock(lockID)
      If (gotLock) Then   
         Msgbox ID & " Got lock: " & lockID & " - at: " & _
           Now() 
         refcnt = Codelockcheck(lockID)
         Msgbox ID & "      Reference count is " & refcnt
         ' Do some meaningful work here, or just sleep
         Sleep 1
      Else
         Msgbox ID & "Failed to get lock"
      End If
      ' Release the lock so the other agent can get it. 
      releaseLock = Codeunlock(lockID)
      If (releaseLock) Then
         Msgbox ID & " Releasing lock: " & lockID & _
           " - at: " & Now() 
         ' Sleep here allows the other agents to obtain 
         ' the lock before this agent has a chance to.
         Sleep 1
      Else
         Msgbox ID & "Failed to release lock"
      End If
   Next
   ' When we are finished, destroy this agent's reference
   ' to the lock
   deleteLock = Destroylock(lockID)
   If (deleteLock ) Then
      Msgbox ID & "Destroyed lock " & lockID
   Else
      Msgbox ID & "Failed to destroy lock"
   End If
   Msgbox  ID & "Done "
   Exit Sub
syn_error:
   errormsg  = "  * * Error: " & Err & " - " &  Error() & _
    " in " & ID & " at " & Erl()
   Msgbox errormsg 
   Resume Next
End Sub

A sample output of Comm1 (with an ID of tuvwx:5706) and Comm2 (with an ID of uvwxy:5742) running concurrently as agents through the Domino® Web server would look something like the following:

Note: Your results will not be identical; due to the nature of asynchronous system locks, you can never predict when specific events will occur.

Addin: Agent message box: Comm1 tuvwx:5706 Started Addin: Agent message box: Comm1 tuvwx:5706 Created lock: 0 Addin: Agent message box: Comm2 uvwxy:5742 Started Addin: Agent message box: Comm2 uvwxy:5742 Created lock: 0 Addin: Agent message box: Comm1 tuvwx:5706 Got lock: 0 - at: 2/10/99 1:57:06 PM Addin: Agent message box: Comm1 tuvwx:5706 Reference count is 1 Addin: Agent message box: Comm2 uvwxy:5742 Got lock: 0 - at: 2/10/99 1:57:07 PM Addin: Agent message box: Comm2 uvwxy:5742 Reference count is 1 Addin: Agent message box: Comm1 tuvwx:5706 Releasing update_lock: 0 - at: 2/10/99 1:57:07 PM Addin: Agent message box: Comm2 uvwxy:5742 Releasing update_lock: 0 - at: 2/10/99 1:57:08 PM Addin: Agent message box: Comm1 tuvwx:5706 Got lock: 0 - at: 2/10/99 1:57:08 PM Addin: Agent message box: Comm1 tuvwx:5706 Reference count is 1 Addin: Agent message box: Comm2 uvwxy:5742 Got lock: 0 - at: 2/10/99 1:57:09 PM Addin: Agent message box: Comm2 uvwxy:5742 Reference count is 1 Addin: Agent message box: Comm1 tuvwx:5706 Releasing lock: 0 - at: 2/10/99 1:57:09 PM Addin: Agent message box: Comm2 uvwxy:5742 Releasing lock: 0 - at: 2/10/99 1:57:10 PM Addin: Agent message box: Comm1 tuvwx:5706 Got lock: 0 - at: 2/10/99 1:57:10 PM Addin: Agent message box: Comm1 tuvwx:5706 Reference count is 1 Addin: Agent message box: Comm2 uvwxy:5742 Got lock: 0 - at: 2/10/99 1:57:12 PM Addin: Agent message box: Comm2 uvwxy:5742 Reference count is 1 Addin: Agent message box: Comm1 tuvwx:5706 Releasing lock: 0 - at: 2/10/99 1:57:12 PM Addin: Agent message box: Comm2 uvwxy:5742 Releasing lock: 0 - at: 2/10/99 1:57:13 PM Addin: Agent message box: Comm1 tuvwx:5706 Got lock: 0 - at: 2/10/99 1:57:13 PM Addin: Agent message box: Comm1 tuvwx:5706 Reference count is 1 Addin: Agent message box: Comm2 uvwxy:5742 Got lock: 0 - at: 2/10/99 1:57:14 PM Addin: Agent message box: Comm2 uvwxy:5742 Reference count is 1 Addin: Agent message box: Comm1 tuvwx:5706 Releasing lock: 0 - at: 2/10/99 1:57:14 PM Addin: Agent message box: Comm2 uvwxy:5742 Releasing lock: 0 - at: 2/10/99 1:57:15 PM Addin: Agent message box: Comm1 tuvwx:5706 Got lock: 0 - at: 2/10/99 1:57:15 PM Addin: Agent message box: Comm1 tuvwx:5706 Reference count is 1 Addin: Agent message box: Comm2 uvwxy:5742 Got lock: 0 - at: 2/10/99 1:57:16 PM Addin: Agent message box: Comm2 uvwxy:5742 Reference count is 1 Addin: Agent message box: Comm1 tuvwx:5706 Releasing lock: 0 - at: 2/10/99 1:57:16 PM Addin: Agent message box: Comm2 uvwxy:5742 Releasing lock: 0 - at: 2/10/99 1:57:18 PM Addin: Agent message box: Comm1 tuvwx:5706 Destroyed lock 0 Addin: Agent message box: Comm1 tuvwx:5706 Done Addin: Agent message box: Comm2 uvwxy:5742 Destroyed lock 0 Addin: Agent message box: Comm2 uvwxy:5742 Done

These primitives are used only for communication between instances of cooperating LotusScript® agents within a single process. They are designed specifically for asynchronous Web agents.

Supported platforms include Win32, OS/2, UNIX (Solaris, HPUX, AIX®), and Alpha-NT.