Thanks very much for your notes Olaf.
I've done as you suggest... I already had SQLITE_THREADSAFE=2 defined, but
didn't have the SQLITE_OMIT_SHARED_CACHE asserted (assuming private cache to be
the default).
The Objective-C method that each thread calls to do the actual querying
(bracketed only by timing logic) is:
/*!
* Get the array of all results of the agents query
*/
- (NSArray *)agentDetails {
sqlite3_stmt *statement;
NSMutableArray *rowsArray = nil;
// TTT
sqlite3 *database;
if (sqlite3_open_v2([DBFILE UTF8String], &database, 0, NULL) !=
SQLITE_OK)
NSAssert1(0, @"Failed to open database with message '%s'.",
sqlite3_errmsg(database));
if (sqlite3_prepare_v2(database, [AGENT_DETAILS_SQL UTF8String], -1,
&statement, NULL) == SQLITE_OK) {
rowsArray = [NSMutableArray arrayWithCapacity:1000];
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString *login =
stringOrEmpty(sqlite3_column_text(statement, 0));
NSString *datasetID =
stringOrEmpty(sqlite3_column_text(statement, 1));
NSString *fullName =
stringOrEmpty(sqlite3_column_text(statement, 2));
NSString *lastName =
stringOrEmpty(sqlite3_column_text(statement, 3));
NSString *firstName =
stringOrEmpty(sqlite3_column_text(statement, 4));
// Make a row dictionary
NSDictionary *rowDict = [NSDictionary
dictionaryWithObjectsAndKeys:
login,
@"login",
datasetID, @"datasetID",
fullName, @"fullName",
lastName, @"lastName",
firstName, @"firstName",
nil];
[rowsArray addObject:rowDict];
}
} else {
NSAssert1(0, @"Failed to run query.\nError message '%s'.",
sqlite3_errmsg(database));
}
// Finish statement
sqlite3_finalize(statement);
// TTT
sqlite3_close(database);
return rowsArray;
}
The results are similar to before:
010-03-05 09:08:57.916 SQLiteTest[76760:a0f] SQLite says multithreading is ON
2010-03-05 09:08:57.918 SQLiteTest[76760:a0f] SQLite's multithreading value is 2
2010-03-05 09:08:57.921 SQLiteTest[76760:5503] Starting query on thread
<NSThread: 0x10050bbc0>{name = (null), num = 4}
2010-03-05 09:08:57.921 SQLiteTest[76760:1b03] Starting query on thread
<NSThread: 0x100511430>{name = (null), num = 3}
2010-03-05 09:08:57.921 SQLiteTest[76760:5603] Starting query on thread
<NSThread: 0x102e07080>{name = (null), num = 5}
2010-03-05 09:08:57.921 SQLiteTest[76760:4403] Starting query on thread
<NSThread: 0x100223820>{name = (null), num = 2}
2010-03-05 09:08:57.921 SQLiteTest[76760:5703] Starting query on thread
<NSThread: 0x10051e980>{name = (null), num = 6}
2010-03-05 09:09:08.561 SQLiteTest[76760:5803] Starting query on thread
<NSThread: 0x103037e00>{name = (null), num = 7}
2010-03-05 09:09:08.619 SQLiteTest[76760:5603] Finished query on thread
<NSThread: 0x102e07080>{name = (null), num = 5} in 10.70s
2010-03-05 09:09:08.620 SQLiteTest[76760:1b03] Finished query on thread
<NSThread: 0x100511430>{name = (null), num = 3} in 10.70s
2010-03-05 09:09:08.620 SQLiteTest[76760:4403] Finished query on thread
<NSThread: 0x100223820>{name = (null), num = 2} in 10.70s
2010-03-05 09:09:08.620 SQLiteTest[76760:5503] Finished query on thread
<NSThread: 0x10050bbc0>{name = (null), num = 4} in 10.70s
2010-03-05 09:09:08.620 SQLiteTest[76760:5703] Finished query on thread
<NSThread: 0x10051e980>{name = (null), num = 6} in 10.70s
2010-03-05 09:09:10.446 SQLiteTest[76760:5803] Finished query on thread
<NSThread: 0x103037e00>{name = (null), num = 7} in 1.88s
2010-03-05 09:09:10.449 SQLiteTest[76760:a0f] Finished all queries in 12.53s
I'm not familiar with the details of your last paragraph, specifically "dynamic
access-mode-switches", but at some cost of time I could try a similar
experiment on Linux to see if the behaviour differs. As noted, this is
currently all running on Mac OS X 10.6 (Snow Leopard).
Perhaps there are few people trying to get truly concurrent querying across
multiple threads in this manner, but naturally I'd be interested to hear from
any others running on the Mac who might have some related experience.
-- Luke
On 2010-03-05, at 3:50 AM, Olaf Schmidt wrote:
>
> "Luke Evans" <[email protected]> schrieb im Newsbeitrag
> news:[email protected]...
>
>> It's Objective-C, but all the SQLite interfacing bits are pure C
>> directly driving the SQLite API compiled into the program
>> (3.6.22 amalgamation).
> Just to make sure ... do you really create different DB-Handles
> (over dedicated DBOpen-Calls) in each of your threads?
>
> Aside from that, could you recompile the SQLite-library
> on your system explicitely with:
> SQLITE_THREADSAFE=2
> and
> SQLITE_OMIT_SHARED_CACHE
>
> And then just open the DBHandles without giving
> explicit "sqlite_open_v2() Flags"?
>
> Maybe (if that solves these "serialized Read-access-issues")
> it could indicate, that the "dynamic access-mode-switches"
> in sqlite_open_v2() do not work as expected in threaded
> mode (at least on your system-OS).
>
> Olaf
>
>
>
>
>
>
>
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users