Link to home
Start Free TrialLog in
Avatar of icd
icd

asked on

Thread-safe DLL. How?

I developed an application, the details don't matter, that processes a file. As an exe file it works fine.
It then became apparent that I needed to code it as a DLL. Once again it worked OK when called from one application.

The problem is that I nead to make it thread-safe. I think I understand the issues, and why they are issues, but would welcome some discussion to help me fully understand.

1. In a multi-thread environment the main problem is static (global) data in the DLL. Since the data area is shared between all instances of the DLL, called from different applications/threads then modification of a static value in one thread will affect the operation of another thread.
2. Stack variables are safe. These are on the application/thread stack and so are separate instances.
3. I need to use a thread-safe version of any standard libraries (I am using MSVC 5)

Now I have created a safe version of my DLL which ensures a thread will not run until a semaphore indicates that the currently running thread is complete, but this is not satisfactory since the DLL is now effectively back to being a single thread with all other threads suspended until they can 'get-in'

Have I correctly identified all of the issues here or are there any others that may 'bite-me'?

Modification of my code to remove all static data is a very big job but I think this is the only approach I can take. Has anyone any suggestions for 'good-practice' when coding in C? (The program is primarily written in C not C++).

Recards
ICD
Avatar of jkr
jkr
Flag of Germany image

>>Since the data area is shared between all instances of
>>the DLL

This is not quite correct - see http://support.microsoft.com/support/kb/articles/Q109/6/19.asp ("HOWTO: Share All Data in a DLL")

"Win32 dynamic-link libraries (DLLs) use instance data by default, meaning that each application that uses a DLL gets its own copy of the DLL's data"

>>Modification of my code to remove all static data is a
>>very big job but I think this is the only approach

Should not be necessary...


>>I need to use a thread-safe version of any standard
>>libraries

That's correct.
Avatar of robpitt
robpitt

Actually my understanding is that the default behaviour for a win32 DLL effectively does give each process its own global variables. (That is unless you've explicitly put global variable into a shared section with #pragma dataseg(shared) )

You could easily test the above with a couple o ftest programs.
Oops, I'm being an echo.
Avatar of icd

ASKER

jkr, robpitt

Now that is funny, I had originally thought that data was not shared and someone convinced me otherwise!

I will have to re-visit the problem and see if there is another reason for the problem.

Basically what happened was that I created a DLL and someone else made calls to from multiple threads and then convinced me that the reason it did not work was because I had not made the program multi-threaded.

It seems I will have to knock up a test program pretty sharpish.

Thanks both. I will think about how to award the points later, when I get back to work.
If you refer to Win32s, then yes, the data in a DLL is shared by all process that use the DLL. this was the behavior for earlier version of Windows. But with Windows 95, NT onwards it is the other way rough. The data is per process and is not shared unless you use the #pragma data_seg directive.
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of icd

ASKER

Madshi.

I think that your comment explains a lot. I believe the calling application is spawning multiple threads. This explains everything.

The problem now comes down to how best to make my program thread safe (something I have not had to do before).

>> 1. In a multi-thread environment the main problem is static (global) data in the DLL. Since the data
area is shared between all instances of the DLL, called from different applications/threads then modification
of a static value in one thread will affect the operation of another thread.

No, it's more this one:
1. In a multi-thread environment the main problem is static (global) data in the DLL. Since the data area is the same in all threads of one process then modification of a static value in one thread will affect the operation of another thread.

>> 2. Stack variables are safe. These are on the application/thread stack and so are separate instances.

Yep, because each thread has its own stack.

>> 3. I need to use a thread-safe version of any standard libraries (I am using MSVC 5)

I'm a Delphi programmer, so I don't know about C++. Are there thread-safe-versions and non-thread-safe versions? I've no idea...

>> Have I correctly identified all of the issues here or are there any others that may 'bite-me'?

Well, yes, the problem are the global variables, that's right. Eventually hardware resources, but that's a rare situation...

>> Modification of my code to remove all static data is a very big job but I think this is the only approach
I can take. Has anyone any suggestions for 'good-practice' when coding in C? (The program is primarily
written in C not C++).

The usual way is to protect the usage of global variables. Sometimes you don't come around using global variables. It works this way: Each time you want to access a global variable (regardless whether you want to read or write it) you have to make sure that no other thread is accessing it at the same time. You can realize it like this:

EnterCriticalSection(sectionForVar1);
try
  access the variable var1
finally
  LeaveCriticalSection(sectionForVar1);
end;

That's all. It's much better for performance than your semaphore solution, because all the threads may run at the same time, only access to global variables is synchronized. No big performance penalty...

Windows itself uses critical sections all day long internally...

Regards, Madshi.
ICD, I guess Madshi has explained it all very well here. You can just enclose the useage of the data in critical section. Using it a function level will cause more penalty.
Avatar of icd

ASKER

Madshi

On the whole you gave me the most information to put me back on the right track. Thanks and thanks to all the other experts that contributed.

ICD