Solved

Accessing variables in multithreading

Posted on 2001-08-04
21
309 Views
Last Modified: 2007-12-19
Hello,
I've got a variable, which is global: CDaoDatabase db;
I've got a function - it uses this variable.
I have a thread, which calls this function, which uses variable <db>.
It gives me an access violation when this function is getting called by thread(when I do db.Execute(SQL)), but it's not, when it's getting called by the program, which started the thread.
Can you help me, I need to use this variable - <db> when the function is been called from the thread. Why it dives me an access violation ?
Thanks.
0
Comment
Question by:MSafine
  • 7
  • 6
  • 4
  • +2
21 Comments
 
LVL 10

Expert Comment

by:makerp
ID: 6351217
listening
0
 
LVL 22

Expert Comment

by:nietod
ID: 6351271
Is the db object being used by two or more threads?  If so you must synchronize access to the object (usually) using a critical section.

For example, if the primary thread opens the database but the 2nd thread uses the db object, you need to insure that these two actions do not occur simultaneously.   In this case it would be possible to do this be opening the database from the 1st thread before even creating the 2nd thread.  But for more complex cases a synchronization device will be needed.

Otherwise we need to see the code.
0
 
LVL 10

Expert Comment

by:makerp
ID: 6351314
the underlying database connection for CDatabase is thread safe, it is specified in the ODBC user guide and that is what it is built on (ODBC API calls). CDao... is tuned for Access and may not use ODBC

SqlAllocEnv for ODBC

"On operating systems that support multiple threads, applications can use the same henv on different threads and drivers must therefore support safe, multithreaded access to this information"

i would either move over to CDatabase (which will be better for portability between different databases, for example access -> oracle etc) or wrap all access to your database object in a critical section
0
 
LVL 10

Expert Comment

by:makerp
ID: 6351317
i have looked through the code and i can not see ODBC calls in CDao's implementation
0
 
LVL 10

Expert Comment

by:makerp
ID: 6351323
the MFC may have a problem with using the connection in a thread that does not own the object (the connection)..
0
 
LVL 22

Expert Comment

by:nietod
ID: 6351338
>> the underlying database connection
>> for CDatabase is thread safe,
It would have to be.  It actualy has to be safe for access not only from multiple threads, but from multiple proccesses running on multiple machines.  

However you still need to syncronize access to the database object.  At least in terms of openeing and using the database, but almost certainly in terms of all operations.  (It is possible to make an object that would not require synchronization, but unless you know that was done, there is a good chance it wasn't done and you can't risk it.)

I definitely think we need to see the code...
0
 
LVL 10

Expert Comment

by:makerp
ID: 6351388
yes, code will help, even though the database connection will be thread safe it is wrapped in an object, therefore other things in the object may not be thread safe, so yes critical sections.

also just out of interest try changing it tp CDatabase, then we can see if just a problem with CDao.

neitod, is there any chance the object could be coded in such a way as to only allow the thread that created it access it?

Paul
0
 
LVL 22

Expert Comment

by:nietod
ID: 6351560
>> the object could be coded in such a way as
>> to only allow the thread that
>> created it access it?
Yes, but they woudl have to go to some trouble to do so, and for no apparent beneft so this is unlikely.  (I suppose its possible that there might actually be a benefit, it which case it could be likely, but I can't think of any.)
0
 

Expert Comment

by:barzangy
ID: 6351998
I think that the function being called has to be reentrant. i.e it should be possible for two threads to call it without problems. this means that the object has to have reentrant methods.

Another possibility is to make the database connection inside the function and make the changes necessary with the help of parameters.

I hope this will help.
0
 

Author Comment

by:MSafine
ID: 6352261
In fact, this short peace of code with the databese is giving me the Access violation too, when the function is being called from the thread:

CDaoDatabase db1;
db1.Open(_T("db1.mdb"));  <-here the accesss violation.

When it's not being called from the thread, no problem.
The database was closed at that moment and so no any other object/function was using it.
This is very strange. It look like it's not recognizing that db1 is a database object. Also when it gives me a choice to debug, it takes me into assembley code.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 49

Accepted Solution

by:
DanRollins earned 100 total points
ID: 6352500
I think that these problems releate to the implicit calls to AfxDaoInit and AfxDaoTerm.  Try making implicit calls, from withing the thread.  This test works for me:

#include <afxdao.h>

UINT MyThreadProc( LPVOID pParam )
{
    AfxDaoInit();
    CDaoDatabase db1;
    db1.Open( "d:\\datasrcs\\world.mdb" );  
    AfxMessageBox("db open was called");
    db1.Close();
    AfxMessageBox("db close was called");
    AfxDaoTerm();
    return 0;   // thread completed successfully
}
void CD6Dlg::OnButton1()
{
   CWinThread* p= AfxBeginThread(MyThreadProc,0 );
}

=--==-=-=-=-=-=-=-
Most variations either cause errors either on attempting to use db1 fns  or when the program terminates.  

Note that AfxDaoTerm() modifies an app-global variable AfxGetApp()->m_lpfnDaoTerm, setting it to NULL.  When non-NULL, then in the normal MFC app termination calls the fn to which it points.  I'll guess that that address is invalid by the time that fn has been called.

Anyway, AfxGetApp()->m_lpfnDaoTerm is a singleton and it seems to be thread-specific.  I looked for warnings about this, but nothing popped out.  There is a discussion in technote 54 about using DAO in a DLL and other stuff.  That leads me to believe that these extra steps are needed.

If you can't create a per-thread copy of the DB, then I suggest switching to ODBC (or perhaps ADO or OLEDB) access to the database.  DAO is several generations old.

-- Dan
0
 
LVL 22

Expert Comment

by:nietod
ID: 6352502
We need to see the code.
0
 
LVL 10

Expert Comment

by:makerp
ID: 6352806
i would move over to CDatabase and CRecordSet
0
 

Expert Comment

by:barzangy
ID: 6352973
What I encountered once with threads was the fact that you put an object on the stack of the thread, I don't know how big is this object and whether calls to that object needs aome more stack. If the stack is too small you'll get an access violation indeed. so try to allocate the object on the heap like this:

CDaoDatabase * db1 = new CDaoDatabase();

And don't forget to free the heap memory at the end.

delete db1;
0
 
LVL 22

Expert Comment

by:nietod
ID: 6353009
In win32 by default you start out with 1 meg of stack space per thread and that EXPANDS as needed.  I suspect that he/she is not running out of stack space.
0
 

Author Comment

by:MSafine
ID: 6353800
Thanks, it worked!
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6353976
I'm happy to help MSafine.  Thank goodness nobody locked this question with an answer.  Otherwise I'd have never seen it.

-- Dan
0
 
LVL 22

Expert Comment

by:nietod
ID: 6353985
If someone had locked it with an answer, you wouldn't need to see it!
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6354025
>>If someone had locked it with an answer, you wouldn't need to see it!

Why? Because MSafine should be forced to find the solution "between the lines" in posts that don't even address the core issue?  

I think that EE Users deserve all of the help they can get from the experts that know how to research and solve such problems.  They don't need help from experts who only know how to click the [Answer] button.  But that is just one man's opinion.  Obviously, opinions vary here.

-- Dan
0
 
LVL 22

Expert Comment

by:nietod
ID: 6354067
But if someone had answered the question who cares if you post to it or not?

If someone else has the answer why is it important that YOU be able to post the answer?  

>> They don't need help from experts who only
>> know how to click the [Answer]
If someone doesn't know the answer, they shouldn't be clicking the answer button.  If they do know the answer, then what is your problem?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6357022
My mistake.  Thanks for correcting me.

-- Dan
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now