Thread safety of serialized mode

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
57 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Thread safety of serialized mode

Bob Friesenhahn
One of our Linux programs (not written by me) is reporting errors of
the form "SQLITE_CORRUPT: database disk image is malformed database
corruption".  Due to timing constraints, it performs all read queries
in one thread and creates a temporary POSIX thread for each update
query (this is the developer's reasoning).  Due to memory constraints
(at least 1MB is consumed per connection!), only one database
connection is used.  Any thread may acquire and use this one database
connection at any time.

The connection open mode is RW,FULLMUTEX (equivalent to
SQLITE_CONFIG_SERIALIZED).

A few queries may use sqlite3_exec() but most queries done by this
program use sqlite3_prepare_v2()/sqlite3_step()/sqlite3_column_foo()
and prepared statements.

The documentation at https://www.sqlite.org/threadsafe.html seems
unclear in that it claims thread safety without documenting under
which use cases it is thread safe.

If we have two threads executing sqlite3_step() on the same connection
and using their own prepared statement, is there any magic in sqlite3
which would keep sqlite3_step() and sqlite3_column_foo() from
consuming (or disrupting) the results from the other thread?

In this use case is sqlite3 usage "thread safe" or is behavior
unstable due to sqlite3_step(), sqlite3_reset(), and result column
accessors accessing/disrupting data from the result set of the other
thread?

Thanks,

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Simon Slavin-3

On 14 Feb 2017, at 11:51pm, Bob Friesenhahn <[hidden email]> wrote:

> One of our Linux programs (not written by me) is reporting errors of the form "SQLITE_CORRUPT: database disk image is malformed database corruption".

Is the database actually corrupt ?  Even if your other threads are not reporting this corruption, it may be real until you’ve checked.  Can you use the shell tool to execute

PRAGMA integrity_check

on it and find out ?

Simon.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Bob Friesenhahn
On Wed, 15 Feb 2017, Simon Slavin wrote:

>
> On 14 Feb 2017, at 11:51pm, Bob Friesenhahn <[hidden email]> wrote:
>
>> One of our Linux programs (not written by me) is reporting errors of the form "SQLITE_CORRUPT: database disk image is malformed database corruption".
>
> Is the database actually corrupt ?  Even if your other threads are
> not reporting this corruption, it may be real until you’ve checked.
> Can you use the shell tool to execute

I don't know if it is corrupt.  I added query code to the program
which reports the problem, causes a core dump, and then the whole
device reboots.  Queries written by someone else just prints a message
and carries on.  We use a design in that the working database is in a
RAM disk and so after the device reboots, the problem database is
gone.

Sometimes sqlite3_step() reports the problem and sometimes
sqlite3_finalize() reports the problem.

> PRAGMA integrity_check
>
> on it and find out ?

I may be able to add code which automatically does this.

It is noteworthy that none of the other programs are encountering this
problem, yet all of those programs perform SQL queries from just one
thread.  Some developers did try to do queries from multiple threads
and encountered severe problems and so they changed their design to
use just one thread.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Richard Hipp-3
In reply to this post by Bob Friesenhahn
On 2/14/17, Bob Friesenhahn <[hidden email]> wrote:
> Due to memory constraints
> (at least 1MB is consumed per connection!), only one database
> connection is used.  Any thread may acquire and use this one database
> connection at any time.

<rant> This is yet another reason why I say "threads are evil".  For
whatever reason, programmers today think that "goto" and pointers and
assert() are the causes of all errors, but threads are cool and
healthful.  Entire programming languages are invited (I'm thinking of
Java) to make goto and pointers impossible or to make assert()
impossible (Go) and yet at the same time encourage people to use
threads.  It boggles the mind.... </rant>

>
> If we have two threads executing sqlite3_step() on the same connection
> and using their own prepared statement, is there any magic in sqlite3
> which would keep sqlite3_step() and sqlite3_column_foo() from
> consuming (or disrupting) the results from the other thread?

Yes, that is suppose to work.  If you find a (reproducible) case where
it does not, we will look into it.

>
> In this use case is sqlite3 usage "thread safe" or is behavior
> unstable due to sqlite3_step(), sqlite3_reset(), and result column
> accessors accessing/disrupting data from the result set of the other
> thread?
>


--
D. Richard Hipp
[hidden email]
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Jens Alfke-2
In reply to this post by Bob Friesenhahn

> On Feb 14, 2017, at 3:51 PM, Bob Friesenhahn <[hidden email]> wrote:
>
> Due to timing constraints, it performs all read queries in one thread and creates a temporary POSIX thread for each update query (this is the developer's reasoning).

To me that seems kind of backwards, since SQLite supports multiple readers but only one writer. In other words, reads can be parallelized [if you use multiple connections], but it’s not possible to perform more than one write at a time. For example, I’m told the .NET SQLite library keeps a pool of connections for reads, but uses a single connection for writes.

> Due to memory constraints (at least 1MB is consumed per connection!), only one database connection is used.  Any thread may acquire and use this one database connection at any time.

With only one connection I don’t think you get any real parallelism. The docs aren’t explicit, but my understanding is that in serialized mode every SQLite API call goes through a mutex belonging to the connection, so only one thread can be acting on that connection at a time.

> If we have two threads executing sqlite3_step() on the same connection and using their own prepared statement, is there any magic in sqlite3 which would keep sqlite3_step() and sqlite3_column_foo() from consuming (or disrupting) the results from the other thread?

Not if they’re using the same statement. A statement is a stateful object, so using it on multiple threads is probably going to cause problems.

Other ways to get in to trouble include
* Iterating over a statement’s result set in one thread while mutating the database on another thread, which results in “undefined results” from the iteration (I just got burned by this a few weeks ago)
* Beginning and ending transactions on multiple threads, since the transaction is shared state of the connection.

Again, my understanding is that SQLite’s thread-safety just says that it won’t crash or corrupt memory or databases, if called on multiple threads. The semantics of the API still mean that you’re not going to get the results you want if you’re not careful about which thread calls what when.

(FYI, this is why I think making APIs thread-safe is a waste of time. Even if you do so, the higher level calling patterns still need to be synchronized correctly by the client code, in which case the lower level thread safety is largely unnecessary. And the overhead of all those mutex locks can be pretty high.)

—Jens
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Darren Duncan
In reply to this post by Richard Hipp-3
On 2017-02-14 4:46 PM, Richard Hipp wrote:
> <rant> This is yet another reason why I say "threads are evil".  For
> whatever reason, programmers today think that "goto" and pointers and
> assert() are the causes of all errors, but threads are cool and
> healthful.  Entire programming languages are invited (I'm thinking of
> Java) to make goto and pointers impossible or to make assert()
> impossible (Go) and yet at the same time encourage people to use
> threads.  It boggles the mind.... </rant>

There is nothing inherently wrong with threads in principle, just in how some
people implement them.  Multi-core and multi-CPU hardware is normal these days
and is even more the future.  Being multi-threaded is necessary to properly
utilize the hardware, or else we're just running on a single core and letting
the others go idle.  The real problem is about properly managing memory.  Also
giving sufficient hints to the programming language so that it can implicitly
parallelize operations.  For example, want to filter or map or reduce a relation
and have 2 cores, have one core evaluate half the tuples and another evaluate
the other half, and this can be implicit simply by declaring the operation
associative and commutative and lacking of side-effects or whatever. -- Darren
Duncan

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Jens Alfke-2
In reply to this post by Richard Hipp-3

> On Feb 14, 2017, at 4:46 PM, Richard Hipp <[hidden email]> wrote:
>
> <rant> This is yet another reason why I say "threads are evil”.  

I agree, and it’s a pretty widely held opinion these days, going back at least to Edward Lee’s 2006 paper “The Problem With Threads”.[1] Actually the problem isn’t threads per se, but sharing mutable data between threads. There is a lot of work these days going into alternative concurrency mechanisms that are safer to use.

> Entire programming languages are invited (I'm thinking of
> Java) to make goto and pointers impossible or to make assert()
> impossible (Go) and yet at the same time encourage people to use
> threads.

Well, both Java and Go have pointers, including the dreaded null, just not pointer arithmetic or uninitialized pointers. And Go has had assertions for a while now. :)

One of the bad things about Java is that it made threads so easy to use that they became an “attractive nuisance” in the hands of inexperienced or careless programmers.
Go, to its credit, reintroduced the “channel” mechanism from CSP, a much safer way for threads to communicate. But channels are limited and somewhat slow, and Go still lets you mess with shared data and mutexes.

The really interesting work is going on in new languages like Rust and Pony that make it impossible to share mutable state between threads. They let you express the idea of moving data, so one thread can hand off state to another without copying.

—Jens

[1]: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Scott Hess
In reply to this post by Darren Duncan
On Tue, Feb 14, 2017 at 5:05 PM, Darren Duncan <[hidden email]>
wrote:

> On 2017-02-14 4:46 PM, Richard Hipp wrote:
>
>> <rant> This is yet another reason why I say "threads are evil".  For
>> whatever reason, programmers today think that "goto" and pointers and
>> assert() are the causes of all errors, but threads are cool and
>> healthful.  Entire programming languages are invited (I'm thinking of
>> Java) to make goto and pointers impossible or to make assert()
>> impossible (Go) and yet at the same time encourage people to use
>> threads.  It boggles the mind.... </rant>
>>
>
> There is nothing inherently wrong with threads in principle, just in how
> some people implement them.  Multi-core and multi-CPU hardware is normal
> these days and is even more the future.  Being multi-threaded is necessary
> to properly utilize the hardware, or else we're just running on a single
> core and letting the others go idle.  The real problem is about properly
> managing memory.  Also giving sufficient hints to the programming language
> so that it can implicitly parallelize operations.  For example, want to
> filter or map or reduce a relation and have 2 cores, have one core evaluate
> half the tuples and another evaluate the other half, and this can be
> implicit simply by declaring the operation associative and commutative and
> lacking of side-effects or whatever.


I'm with Dr Hipp - threads are evil.  It's not so much how they work when
everything goes well, it's that it's so challenging to align everything so
that it goes well.  My experience is that even very talented programmers
write bugs into their multi-threaded code without realizing it.  I think
what happens is that multi-threaded code often makes things much more
complicated than they look, so if you write to the limits of the complexity
you can understand, you're already over your head.

IMHO, if you're using a message-passing system which does implicit
parallelization, well, _you're_ not using threads, the implementation is
using threads on your behalf.  That I can get behind.  Unfortunately,
decent systems along those lines are like nuclear fusion, they've been just
around the corner for decades, now :-).

-scott
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Richard Hipp-3
In reply to this post by Darren Duncan
On 2/14/17, Darren Duncan <[hidden email]> wrote:
>
> There is nothing inherently wrong with threads in principle,

Nor is there anything wrong with goto, pointers, and assert(), in
principle.  And yet they are despised while threads are adored, in
spite of the fact that goto/pointer/assert() errors are orders of
magnitude easier to understand, find, and fix.

--
D. Richard Hipp
[hidden email]
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Jens Alfke-2

> On Feb 14, 2017, at 5:15 PM, Richard Hipp <[hidden email]> wrote:
>
> Nor is there anything wrong with goto, pointers, and assert(), in
> principle.  And yet they are despised while threads are adored, in
> spite of the fact that goto/pointer/assert() errors are orders of
> magnitude easier to understand, find, and fix.

Goto and pointers don’t enable huge speed increases the way concurrency does. With clock speed having stalled, the only way to take advantage of modern CPUs (and GPUs!) is to go parallel. Threading is also important to keep the UI responsive in GUI apps.

Goto is pretty much unnecessary except occasionally for error handling in C since it doesn’t have any proper cleanup mechanisms. I haven’t used it in years (and yeah, my programming history goes back to the late ‘70s, starting with Tiny BASIC on IMSAI 8080s, so don’t tell me to get off your lawn ;-)
Pointer arithmetic likewise except in certain really low-level grungy libraries. I have one such library, but the rest of my code is in C++ and mostly uses smart pointers.
I’ve actually never heard anyone speak negatively about assertions. What’s wrong with them?

—Jens
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Clemens Ladisch
Jens Alfke wrote:
> With clock speed having stalled, the only way to take advantage of
> modern CPUs (and GPUs!) is to go parallel.

But "go parallel" does not necessarily imply threads.  There are many
ways to allow code running on different CPUs(/cores) to communicate
with each other (e.g., files, sockets, message queues, pipes, shared
memory, etc.), and almost all of them are safer than threading because
they do not require that _all_ of the address space and the process
context are shared.  When using threads, all memory accesses are unsafe
by default, and it is then the job of the programmer to manually add
some form of locking to make it safe again.

Threading is the most extreme method of achieving parallelism, and
therefore should be used only as the last resort.  (I'd compare it to
assembly code in this regard.)


Regards,
Clemens
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Dominique Devienne
In reply to this post by Jens Alfke-2
On Wed, Feb 15, 2017 at 2:07 AM, Jens Alfke <[hidden email]> wrote:

> > Entire programming languages are invited (I'm thinking of
> > Java) to make goto and pointers impossible or to make assert()
> > impossible (Go) and yet at the same time encourage people to use
> > threads.
>
> [...]. And Go has had assertions for a while now. :)
>

Really? Where? --DD

Why does Go not have assertions? https://golang.org/doc/faq#assertions
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Cecil Westerhof-5
In reply to this post by Clemens Ladisch
2017-02-15 8:58 GMT+01:00 Clemens Ladisch <[hidden email]>:

> Jens Alfke wrote:
> Threading is the most extreme method of achieving parallelism, and
> therefore should be used only as the last resort.  (I'd compare it to
> assembly code in this regard.)
>

​At the moment I am not using it much and I am certainly not an expert, but
as I understood it one of the reasons to use threading is that it costs a
lot less resources.

--
Cecil Westerhof
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Clemens Ladisch
Cecil Westerhof wrote:
> 2017-02-15 8:58 GMT+01:00 Clemens Ladisch <[hidden email]>:
>> Threading is the most extreme method of achieving parallelism, and
>> therefore should be used only as the last resort.  (I'd compare it to
>> assembly code in this regard.)
>
> ​At the moment I am not using it much and I am certainly not an expert, but
> as I understood it one of the reasons to use threading is that it costs a
> lot less resources.

And just like with assembly code, you also have to count the time spent
writing it, and debugging the result.


Regards,
Clemens
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Darren Duncan
On 2017-02-15 2:40 AM, Clemens Ladisch wrote:

> Cecil Westerhof wrote:
>> 2017-02-15 8:58 GMT+01:00 Clemens Ladisch <[hidden email]>:
>>> Threading is the most extreme method of achieving parallelism, and
>>> therefore should be used only as the last resort.  (I'd compare it to
>>> assembly code in this regard.)
>>
>> ​At the moment I am not using it much and I am certainly not an expert, but
>> as I understood it one of the reasons to use threading is that it costs a
>> lot less resources.
>
> And just like with assembly code, you also have to count the time spent
> writing it, and debugging the result.

Also, its a long time since hand-writing assembly code was any good for
performance, unless you're a 1% top expert with a good reason.

If you want speed, write in C or something else that isn't assembly.  The odds
are like 99% that the modern C compiler will generate faster code than you could
ever write yourself in assembly, and it will be much less buggy.

Similarly with threads, for the vast majority of people, using other concurrency
models with supported languages are better; they will still get the performance
benefit of using multiple CPU cores but do it much more safely than if you are
explicitly using "threads" in code.

-- Darren Duncan

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Cecil Westerhof-5
2017-02-15 12:40 GMT+01:00 Darren Duncan <[hidden email]>:

> Similarly with threads, for the vast majority of people, using other
> concurrency models with supported languages are better; they will still get
> the performance benefit of using multiple CPU cores but do it much more
> safely than if you are explicitly using "threads" in code.


​As I said before: I did not work much with threads. Mostly for GUI
performance. Do you (or anyone else) have any resources about those
concurrency models​?

--
Cecil Westerhof
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
ajm
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

ajm
In reply to this post by Richard Hipp-3
> ---- Mensaje original ----
> De: Richard Hipp <[hidden email]>
> Para:  SQLite mailing list <[hidden email]>
> Fecha:  Tue, 14 Feb 2017 20:15:49 -0500
> Asunto:  Re: [sqlite] Thread safety of serialized mode
>>
> > On 2/14/17, Darren Duncan <[hidden email]> wrote:
>>
> > There is nothing inherently wrong with threads in principle,

> Nor is there anything wrong with goto, pointers, and assert(), in
> principle.  And yet they are despised while threads are adored, in
> spite of the fact that goto/pointer/assert() errors are orders of
> magnitude easier to understand, find, and fix.
>
> --
> D. Richard Hipp

It seems that the problem of writing good multi-threaded programs lies in the limited ability of the human mind to think in parallel, which reminds me of the time when, after learning to use the unfortunate goto, they came to tell us that if we used them, the evil demon would come and burn our toenails, even though the compiler translates all those elegant programs to an enormous amount of jumps in the assembled code.

I suppose someday, programming languages can do an analogous translation in our limited but safe, sequential programs.

--
Adolfo J.M.

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Simon Slavin-3
In reply to this post by Cecil Westerhof-5

On 15 Feb 2017, at 10:16am, Cecil Westerhof <[hidden email]> wrote:

> 2017-02-15 8:58 GMT+01:00 Clemens Ladisch <[hidden email]>:
>
>> Jens Alfke wrote:
>> Threading is the most extreme method of achieving parallelism, and
>> therefore should be used only as the last resort.  (I'd compare it to
>> assembly code in this regard.)
>
> ​At the moment I am not using it much and I am certainly not an expert, but
> as I understood it one of the reasons to use threading is that it costs a
> lot less resources.

Compared with processes, yes.  Threads share stuff.  Processes have their own stuff.  Therefore threads are faster to start up and end (no resources to allocate or release) and don’t take any kind of resource space.

Two disadvantages are that threads are indistinguishable to anything but the owner and don’t know how to keep out of each-other’s way.  By the time you’ve devised some sort of mutex/locking/blocking mechanism you’re usually better-off using processes.

Graphics programs where you can assign one thread per pixel because each pixel has its own colour ?  Threads.
Database programs where everything has to access the same database file ?  Processes.

Simon.
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Bob Friesenhahn
In reply to this post by Richard Hipp-3
On Tue, 14 Feb 2017, Richard Hipp wrote:

> On 2/14/17, Bob Friesenhahn <[hidden email]> wrote:
>> Due to memory constraints
>> (at least 1MB is consumed per connection!), only one database
>> connection is used.  Any thread may acquire and use this one database
>> connection at any time.
>
> <rant> This is yet another reason why I say "threads are evil".  For
> whatever reason, programmers today think that "goto" and pointers and
> assert() are the causes of all errors, but threads are cool and
> healthful.  Entire programming languages are invited (I'm thinking of

Threads are a powerful tool but (like guns) they must be used very
carefully.

In this particular case I think that the developer is making an
assumption that more (partial) threading helps but with serialized
access the database will still block and so perhaps it does not really
help at all.

>> If we have two threads executing sqlite3_step() on the same connection
>> and using their own prepared statement, is there any magic in sqlite3
>> which would keep sqlite3_step() and sqlite3_column_foo() from
>> consuming (or disrupting) the results from the other thread?
>
> Yes, that is suppose to work.  If you find a (reproducible) case where
> it does not, we will look into it.

Thanks for this clarification.  It is quite possible that the bug
is outside of sqlite.  The bug feels like a thread safety issue to me.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Thread safety of serialized mode

Bob Friesenhahn
In reply to this post by Jens Alfke-2
On Tue, 14 Feb 2017, Jens Alfke wrote:
>
>> If we have two threads executing sqlite3_step() on the same connection and using their own prepared statement, is there any magic in sqlite3 which would keep sqlite3_step() and sqlite3_column_foo() from consuming (or disrupting) the results from the other thread?
>
> Not if they’re using the same statement. A statement is a stateful
> object, so using it on multiple threads is probably going to cause
> problems.

To be clear, each thread is using its own prepared statement.

Bob
--
Bob Friesenhahn
[hidden email], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
123