How to Avoid Deadlock Between Modules

In some situations, it may be necessary for you to control the synchronization of modules using facilities other than a thread-serialized module or a serialized procedure. For example, consider the situation shown in Figure 75, where two threads are each running a procedure in different thread-serialized modules: procedure PROC1 in module MOD1 and procedure PROC3 in module MOD2. MOD1 also has procedure PROC2 and MOD2 also has procedure PROC4. Even though there is no actual recursive calling; if PROC1 calls PROC4, it will wait for MOD2 to unlock; and if PROC3 calls PROC2, it will wait for MOD1 to unlock. The procedures will not be able to complete their calls, since each module will be locked by the thread in the other module. This type of problem can occur even with serialization of calls to a module, and is referred to as deadlock.

Figure 75. Deadlock Example in a THREAD(*SERIALIZE) module
Deadlock Example

This example shows how deadlock can occur if you try to access more than one procedure in the same thread-serialized module at the same time.

To avoid the problem in the above example and ensure thread safe applications, you can control the synchronization of modules using the techniques described in Using thread-related APIs. Any callers of PROC1 or PROC3 for each thread should do the following:

  1. Restrict access to the modules for all threads except the current thread, always in the same order (MOD1 then MOD2)
  2. In the current thread, call the required procedure (PROC1 or PROC3)
  3. Relinquish access to the modules for all threads in the reverse order of step 1 (MOD2 then MOD1).

One thread would be successful in restricting access to MOD1. Since all users of MOD1 and MOD2 use the protocol of restricting access to MOD1 and MOD2 in that order, no other thread can call procedures in MOD1 or MOD2 while the first thread has restricted access to the modules. In this situation you have access to more than one procedure in the same module at the same time, but since it is only available to the current thread, it is thread safe.

This method should also be used to synchronize access to shared storage.



[ Top of Page | Previous Page | Next Page | Contents | Index ]