I have a small C++ dll that has 2 callback functions that retrieve information from another dll.
These 2 callback functions are being called repeatedly in more than 1 thread.
They both add information to the same global Cstring variable.
I have another function that the program that uses this dll will call that reads this variable.
It is rare, but sometimes I get a crash and its definitely due to this global variable being read/written to at the same time by 2 different functions.
I am not very experienced with multithreads, so I don't really know what to do.
Any suggestions?
here is a previous question I posted about the same problem with a bit more info..(and some of the code).
One of the users assisted me in confirming that it was a multithread issue and we didnt get much further than that.
C++ DLL crash (reading/writing crash related I think)
Have a read of Thread Synchronization for Beginners.
If you're using MFC then CMutex may be appropriate.
You have to create a critical section on this variable. In Windows, you can do it by using Mutex Objects.
Related
A while back I made a post regarding creating a dll, for the purpose of injection, that will cause the host application to trigger an Nvidia Optimus laptop to "awaken" the dGpu. This being necessary because of the pathetic system nvidia created here which results in MANY applications not recognizing the presence of the power dGpu, and instead using the integrated intel gpu. (Specifically some video processing apps which take hours longer using Intel's than it would Nvidia's). That post was here.
Suffice to say, I moved to work in Antarctica and gave up on the project. I just picked it back up years later and decided to learn (enough) C++ to program it here. I have created the DLL, and if I place the DX code in a function, then call that function from a host "caller" program.. IT WORKS!!! However, if I put that code in the DLLMAIN, and then simply load that dll from my "caller" program (without actually calling a specific function)... the procedure executes!!! However, when it gets to the part of the code where CREATEDEVICE is run, it crashes. I have since learned this is due to an issue called deadlock, or loaderlock.. i'm not sure which. I understand the concept, but don't have anywhere NEAR the C++ understanding to develop a workaround.
So basically.. can I run my procedure in DLLMAIN using some workaround? Maybe spawning an independent thread somehow (so DLLMAIN can finish executing to it's return?) Thanks for any info. I'll include the vcproject source code here.. but it's a Frankenstein of things I found online.. so don't look for elegance- I know next to nothing about C++ programming! http://s000.tinyupload.com/index.php?file_id=07876333208461296171
The loader lock is a lock which is per-process and owned just after you call LoadLibrary, until just before the LoadLibrary returns. It is intended to ensure the process correctly accounts for the loaded DLLs and their order.
There is very little code which can be added in DllMain which doesn't run the risk of a fail, as any Windows call which may cause IPC can fall fowl of the loader-lock.
If you can create a thread from outside the process, or create a second function you can call directly, then this will be a better solution
I wrote a tool in C++ using wxWidgets for the GUI and IBM ILOG Cplex to solve an optimization problem.
In one of the functions called by the wx event handler, I invoke the IBM ILOG Cplex Optimizer which is itself multi-threaded code.
I realize that this causes indererministic bugs with non-sensical memory contents.
Since I have no experince in writing multi-threaded code and would like to get away without spending three weeks learning how to do it, I would like to know:
Is there is some safe, possibly inelegant way to avoid problems here? (More elegant, maybe, than writing a file to disc, calling a different task through the OS and reading the output back in).
Is it a bad idea to launch Cplex threads from a wx thread?
Is it generally a bad idea to use two libraries that might use different libraries internally to implement multi-threading? (I have no idea what there is except pthreads and what is used by either cplex or wx).
Any help and background information is appreciated.
Based on my experience, the rule is:
every wxWdiget function call that change the display must be made in the wxWidget thread
I don't know much about Cplex, but if you say it's multithreaded, chances are you are calling an asynchronous function and you handle the results in a call back. The callback is most definitely not called withing the wxWidget thread. If you then try to display the results within the callback, you are breaking the rule stated above. That's when you'll get nice little bugs, which in my case usually materialize as heap corruption.
To fix that you must pass the results of your callback to the wxWidget thread and display them in that thread. There's many way to do it, but the global mechanism is to trigger a custom event on wxWigdet that get passed to the wxWidget thread.
Check this link, http://wiki.wxwidgets.org/Custom_Events you need to use
wxEvtHandler::AddPendingEvent(wxEvent& event)
The scenario is here:
If a program is executed, at runtime assume it will link to some DLL files, the (master) program/process may or may not create multi-threading function-calls to the functions in DLLs.
Then is there a way that the DLL, of cause besides parameter-passing, can tell whether the master process, who calls the functions within the DLL at runtime, is in a single or multi-thread manner (For instance, by Open MP)?
You can check and compare the current thread ID to detect calls from different threads. You could also implement a DLLMain() function that gets called for every started and terminated thread. I'm pretty sure you can also retrieve a handle to the current process and enumerate the threads running in it. Only the first version will actually tell you if your code is run from different threads though, I think that e.g. WinSock will create a thread for you, even though your program is single-threaded otherwise.
BTW: Consider adding win32api tag and removing C++ tag.
I am developing a DLL in MS VC express c++ that will be loaded in multiple client applications at the same time, the DLL has a shared memory space created using data_seg(".SHARED_SPACE_NAME"). In this shared memory space there are some vectors that can be modified.
Lets assume we have a function in the DLL body called doCalc():
_DLLAPI void __stdcall doCalc(int argument)
{
//Add to vector
//Loop through vector
//Erase from vector
//etc.
}
If doCalc is called at the same time from two or more client applications the system will crash.
I want the doCalc calls to "wait in line" for the previous call to finish - like it was a single-threaded application.
So that if client 1 calls and then immediately after client 2 calls, then client 1 should finish the function, and then client 2 should run the function.
The best solution would be to run the DLL as a single thread but I have searched the internet a I do not think it is possible.
I have tried searching the internet for this issue, and I have come up with something about making the function static would make it thread safe.
I have also read that C++0x somehow will make this thread-safe. But that it is not supported in MS VC express.
I have no experience in multithreading, so I hope you can help. Thanks in advance.
The Windows API to use here would be CreateMutex. Create a named mutex object. As you need to manipulate the shared data, call WaitForSingleObject with the mutex handle, and when you are done, call ReleaseMutex. Each thread that calls WaitForSingleObject takes ownership of the mutex and any other thread that calls WaitForSingleObject will stall, until the owning thread calls ReleaseMutex.
Of course, I don't belive you can do what you want to do:
Dlls may be mapped in at different addresses in each process space. If so, all pointers will be incorrect.
C++ does not allow fine grained control over allocations and has many implicit allocations, especially when dealing with STL objects. I don't belive that you can get the vector to store all the relevant data in the shared area.
You are going to have to do this with C style raw arrays.
Looks like you need a system-wide mutex that will protect your critical section of code (the code that mustn't run simultaneously). Making the function static has nothing to do with it, because it doesn't prevent different applications from running it at the same time.
I think that Boost.Interprocess is exactly what you need. It will solve both, the synchronization problem, and the one that Jim Brissom said in his comment that you even haven't thought about yet.
Few months back, I had come across this interesting scenario asked by a guy (on orkut). Though, I've come up with a "non-portable" solution to this problem (have tested it with small code), but still would like to know what you guys have to say and suggest.
Suppose, I created a DLL, exporting some functionalities, written in C++, for single threaded client. This DLL declares lots of global variables, some maybe const variables (read-only) and others are modifiable.
Anyway, later things changed and now I want the same DLL to work with multi-threaded application (without modifying the DLL); that means, several threads access the functions and global variables from the DLL, and modify them.. and so on. All these may cause global variables to hold inconsistent values.
So the question is,
Can we do something in the client code to prevent multi-access of the DLL, and at the same time, ensuring that each thread runs in it's own context (meaning, when it gets access to the DLL, the DLL's global values are same as it was before)?
Sure, you can always create a wrapper-layer handling multi-threading specific tasks such as locking. You could even do so in a second DLL that links with the original one, and then have the final project link with that new DLL.
Be aware that no matter how you implement it, this won't be an easy task. You have to know exactly which thread is able to modify which value at what time, who is able to read what and when etc. unless you want to run into problems like deadlocks or race conditions.
If you're solution allows it, it's often best to assign a single thread to modify any data, and have all others just read and never write, as concurrent reading access is always easier to implement than concurrent writing access (Boost provides all basic functionality to do so, for example shared_mutex).
Can we do something in the client code to prevent multi-access of the DLL, and at the same time, ensuring that each thread runs in it's own context (meaning, when it gets access to the DLL, the DLL's global values are same as it was before)?
This is the hard part. I think the only way top do this would be to create a wrapper around teh existing DLL. When it is called, it would restore the state (global variables) for the current thread, and save them when the call to the DLL returns. You would need to know all of the state variables in the DLL, and be able to read/write them.
If performance is not an issue, a single lock for the entire DLL would suffice, and be the easiest to implement correctly. That would ensure that only one thread was accessing (reading or writing) the DLL at one time.