C Multithreading - Sqlite3 database access by 2 threads crash

1k views Asked by At

Here is a description of my problem:

I have 2 threads in my program. One is the main thread and the other one that i create using pthread_create

The main thread performs various functions on an sqlite3 database. Each function opens to perform the required actions and closing it when done.

The other thread simply reads from the database after a set interval of time and uploads it onto a server. The thread also opens and closes the database to perform its operation.

The problem occurs when both threads happen to open the database. If one finishes first, it closes the database thus causing the other to crash making the application unusable. Main requires the database for every operation.

Is there a way I can prevent this from happening? Mutex is one way but if I use mutex it will make my main thread useless. Main thread must remain functional at all times and the other thread runs in the background.

Any advice to make this work would be great. I did not provide snippets as this problem is a bit too vast for that but if you do not understand anything about the problem please do let me know.

EDIT:

static sqlite3 *db = NULL;

Code snippet for opening database

int open_database(char* DB_dir) // argument is the db path
        rc = sqlite3_open(DB_dir , &db); 

        if( rc )                
        {
//failed to open message
            sqlite3_close(db); 
            db = NULL;
            return SDK_SQL_ERR;
        }
        else
        {
            //success message
        }
    }
    return SDK_OK;

}

And to close db

int close_database()
{
    if(db!=NULL)
    {
        sqlite3_close(db);
        db = NULL;
        //success message
    }
    return 1;
}

EDIT: I forgot to add that the background thread performs one single write operation that updates 1 field of the table for each row it uploads onto the server

2

There are 2 answers

0
Grady Player On

Basically built into sqlite3 there are mechanisms to provide locking... BEGIN EXCLUSIVE then you can also register a sleep callback so that the other thread can do other things...

see sqlite3_busy_handler()

8
djna On

Have your threads each use their own database connection. There's no reason for the background thread to affect the main thread's connection.

Generally, I would want to be using connection pooling, so that I don't open and close database connections very frequently; connection opening is an expensive operation.

In application servers we very often have many threads, we find that a connection pool of a few tens of connections is sufficient to service requests on behalf of many hundreds of users.