Roushan Ali wrote:
Hi,
Thanks for your response. I don't have any idea how multiple
connection objects work. Can you please tell us something about that.
I wrappered the C interface to SQLite3 via a C++ Class called
"CSqlite3". The constructor does NOT open the database, it just
allocates the sqlite struct.
I declared 4 global instances of this class. The constructors get
called before my WinMain().
In my initialization code (called before any threads are created), I
open the database 4 times. I do an integrity check (and some other
logic) after the first open. Like this:
g_DbMain.Open(szFilename);
CheckDatabase(g_DbMain); // "pragma integrity_check, create missing
tables / schema updates, vacuum"
g_DbTimer.Open(szFilename);
g_DbThread2.Open(szFilename);
g_DbThread3.Open(szFilename);
I then create the worker threads. One of my threads does NOT use any
database, so we'll ignore it. Another thread (main / gui) already
exists, so I am really only creating threads #2 and #3. The thread
function uses the database object as needed.
After the worker threads terminate, the main thread closes all four
database objects. The object's destructor is called when the
application exits.
I do not create new connections to the database while the executing.
Please note that my solution is NOT appropriate if I wanted to create
arbitrary threads at arbitrary times. If I were doing that, then each
thread would create it's own database object on it's own TLS (thread
local storage) or stack. I created all of my database "Open()" code
into the main thread just to keep it all together.
Each of my threads does a very specific function that is totally unique
to that thread:
1. The main thread uses it's database connection to respond to user
initiated GUI events.
2. The main thread also uses the "timer" database connection to
handle WM_TIMER messages to update a status display synchronously
(kinda). Because this function can be invoked while the thread
has a transaction on the main connection, I need to use a
different connection. One thread, but it must be fully re-entrant.
3. Thread #2 is a producer. It gathers data and inserts it into the
database.
4. Thread #3 is a consumer. It takes data from the database and does
stuff with them. It updates those rows.
The timer connection only executes "select" to update the GUI. The main
connection is used to query the database, update the database and to
delete from the database.
The application is what it is. I make no public claims about it being
the best designed thing ever, but it does work well under stress.