alancc
alancc

Reputation: 799

Can two functions in same DLL be called by two threads?

I write a DLL MyDLL.dll with Visual C++ 2008, as follows:

(1) MFC static linked (2) Using multi-thread runtime library.

In the DLL, this is a global data m_Data shared by two export functions, as follows:

    ULONGLONG WINAPI MyFun1(LPVOID *lpCallbackFun1)
    {
        ...
        Write m_Data(using Critical section to protect)
        …

        return  xxx;
    }

    ULONGLONG WINAPI MyFun2(LPVOID *lpCallbackFun2)
    {
        ...
        Suspend MyThread1 to prevent conflict.
        Read m_Data(using Critical section to protect)
        Resume MyThread1.
        …

        return  xxx;
    }

In in my main application, it will first call LoadLibrary to load MyDLL.dll, then get the address of MyFun1 and MyFun2, then do the following thing:

(1) Start a new thread MyThread1, which will invoke MyFun1 to do a time-consuming task. (2) Start a new thread MyThread2, which will invoke MyFun2 for several times, as follows:

    for (nIndex = 0; nIndex = 20; nIndex)
    {
    nResult2 = MyFun2(lpCallbackFun2);
    NextStatement2; 
    }

Although MyThread1 and MyThread2 using critical section to protect the shared data m_Data, I will still suspend MyThread1 before accessing the shared data, to prevent any possible conflicts.

The problem is:

(1) When the first invoke of MyFun2, everything is OK, and the return value of MyFun2(that is nResult2) is 1 , which is expected. (2) When the second, third and fourth invoke of MyFun2, the operations in MyFun2 are executed successfully, but the return value of MyFun2(that is nResult2) is a random value instead of the expected value 1. I try to using Debug to trace into MyFun2, and confirm that the last return statement is just return a value of 1, but the invoker will receive a random value instead of 1 when inspecting nResult2. (3) After the fourth invoke of MyFun2 and return back to the next statement follow MyFun2, I will always get a “buffer overrun detected” error, whatever the next statement is.

I think this looks like a stack corruption, so try to make some tests:

  1. I confirm the /GS (Stack security check) feature in the compiler is ON.
  2. If MyFun2 is invoked after MyFun1 in MyThread1 is completed, then everything will be OK.
  3. In debug mode, the codeline in MyFun2 that reads the shared data m_Data will not cause any errors or exceptions. Neither will the codeline in MyFun1 that writes the shared Data.

So, how to solve this problem

Thank you!

Upvotes: 0

Views: 487

Answers (3)

xMRi
xMRi

Reputation: 15365

Never use SupsendThread!!! NEVER! SuspendThread is only used for Debugging purpose.

The reason is simple. You don't know where you suspend the thread. It may be just in time, when the thread blocks a resource that you want to use. Also a bunch of CRT function use thread synchronisation. Just use critcal sectins or mutexes.

Just see the simple sample here: http://blog.kalmbachnet.de/?postid=6 and here http://blog.kalmbachnet.de/?postid=16

Upvotes: 1

Anton Savin
Anton Savin

Reputation: 41301

I suppose at this line

Suspend MyThread1 to prevent conflict.

you are using SuspendThread() function. That's what its documentation says:

This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.

So, in short: don't use it. Critical sections and other synchronization objects do their job just fine.

Upvotes: 1

rcgldr
rcgldr

Reputation: 28826

Since this is a windows program you could use windows based mutex or semaphore and WaitForSingleObject when reading or writing shared data.

Upvotes: 0

Related Questions