-
August 27th, 2014, 05:58 PM
#1
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!
-
August 27th, 2014, 07:44 PM
#2
Re: Can two functions in same DLL be called by two threads?
Originally Posted by AlanCCC
Suspend MyThread1 to prevent conflict.
How are you suspending the thread? If you're using SuspendThread, that shouldn't be used for synchronization.
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Regards,
Paul McKenzie
-
August 27th, 2014, 08:11 PM
#3
Re: Can two functions in same DLL be called by two threads?
If you are using a critical section [properly] to protect the shared data, there is no reason to have to suspend the thread.
If the return value is some sort of global variable (and isn't protected by the critical section), you will need to synchronize access to it.
-
August 28th, 2014, 01:31 AM
#4
Re: Can two functions in same DLL be called by two threads?
Originally Posted by AlanCCC
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.
It seems your buffer appears overrun at the moment you start getting random return values, so your problem hardly has anything to do with threading or DLL. It's most probably either true corruption of local thread stack or wild pointer dereference.
Best regards,
Igor
-
August 28th, 2014, 06:44 AM
#5
Re: Can two functions in same DLL be called by two threads?
suspending a thread is a bad idea, especially if you try to do it as a means of getting or avoiding synchronisation.
The simple case failure scenario...
* Thread 1 is busy doing some stuff and has left internal data structures in an incomplete/half finished state.
* Thread 2 suspends thread 1
* Thread 2 uses the internal data structures which aren't complete. This is the failure point. "anything could happen" when thread 2 uses the incomplete data. It might even seem thread 2 is working 'ok'.
* Thread 2 resumes thread
* Thread 1 may now have to deal with other stuff Thread2 has done to the incomplete data and causing thread 1 to behave unexpectedly. This could end up being hard to track down since you'll be assuming there's a bug in this code, when the real culprit is in the other thread.
If you ARE using proper synchronisation, then suspending a thread may cause a deadlock.
Even if you guard against that, it may have other issues such as severe performance degradation.
Avoid thread suspension, there are a few edge cases where you need it, but for the most part, it is probably a sign of a serious design flaw.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|