⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_server.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2006 January 07**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.************************************************************************************ This file contains demonstration code.  Nothing in this file gets compiled** or linked into the SQLite library unless you use a non-standard option:****      -DSQLITE_SERVER=1**** The configure script will never generate a Makefile with the option** above.  You will need to manually modify the Makefile if you want to** include any of the code from this file in your project.  Or, at your** option, you may copy and paste the code from this file and** thereby avoiding a recompile of SQLite.****** This source file demonstrates how to use SQLite to create an SQL database ** server thread in a multiple-threaded program.  One or more client threads** send messages to the server thread and the server thread processes those** messages in the order received and returns the results to the client.**** One might ask:  "Why bother?  Why not just let each thread connect** to the database directly?"  There are a several of reasons to** prefer the client/server approach.****    (1)  Some systems (ex: Redhat9) have broken threading implementations**         that prevent SQLite database connections from being used in**         a thread different from the one where they were created.  With**         the client/server approach, all database connections are created**         and used within the server thread.  Client calls to the database**         can be made from multiple threads (though not at the same time!)****    (2)  Beginning with SQLite version 3.3.0, when two or more **         connections to the same database occur within the same thread,**         they can optionally share their database cache.  This reduces**         I/O and memory requirements.  Cache shared is controlled using**         the sqlite3_enable_shared_cache() API.****    (3)  Database connections on a shared cache use table-level locking**         instead of file-level locking for improved concurrency.****    (4)  Database connections on a shared cache can by optionally**         set to READ UNCOMMITTED isolation.  (The default isolation for**         SQLite is SERIALIZABLE.)  When this occurs, readers will**         never be blocked by a writer and writers will not be**         blocked by readers.  There can still only be a single writer**         at a time, but multiple readers can simultaneously exist with**         that writer.  This is a huge increase in concurrency.**** To summarize the rational for using a client/server approach: prior** to SQLite version 3.3.0 it probably was not worth the trouble.  But** with SQLite version 3.3.0 and beyond you can get significant performance** and concurrency improvements and memory usage reductions by going** client/server.**** Note:  The extra features of version 3.3.0 described by points (2)** through (4) above are only available if you compile without the** option -DSQLITE_OMIT_SHARED_CACHE. **** Here is how the client/server approach works:  The database server** thread is started on this procedure:****       void *sqlite3_server(void *NotUsed);**** The sqlite_server procedure runs as long as the g.serverHalt variable** is false.  A mutex is used to make sure no more than one server runs** at a time.  The server waits for messages to arrive on a message** queue and processes the messages in order.**** Two convenience routines are provided for starting and stopping the** server thread:****       void sqlite3_server_start(void);**       void sqlite3_server_stop(void);**** Both of the convenience routines return immediately.  Neither will** ever give an error.  If a server is already started or already halted,** then the routines are effectively no-ops.**** Clients use the following interfaces:****       sqlite3_client_open**       sqlite3_client_prepare**       sqlite3_client_step**       sqlite3_client_reset**       sqlite3_client_finalize**       sqlite3_client_close**** These interfaces work exactly like the standard core SQLite interfaces** having the same names without the "_client_" infix.  Many other SQLite** interfaces can be used directly without having to send messages to the** server as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined.** The following interfaces fall into this second category:****       sqlite3_bind_***       sqlite3_changes**       sqlite3_clear_bindings**       sqlite3_column_***       sqlite3_complete**       sqlite3_create_collation**       sqlite3_create_function**       sqlite3_data_count**       sqlite3_db_handle**       sqlite3_errcode**       sqlite3_errmsg**       sqlite3_last_insert_rowid**       sqlite3_total_changes**       sqlite3_transfer_bindings**** A single SQLite connection (an sqlite3* object) or an SQLite statement** (an sqlite3_stmt* object) should only be passed to a single interface** function at a time.  The connections and statements can be passed from** any thread to any of the functions listed in the second group above as** long as the same connection is not in use by two threads at once and** as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined.  Additional** information about the SQLITE_ENABLE_MEMORY_MANAGEMENT constraint is** below.**** The busy handler for all database connections should remain turned** off.  That means that any lock contention will cause the associated** sqlite3_client_step() call to return immediately with an SQLITE_BUSY** error code.  If a busy handler is enabled and lock contention occurs,** then the entire server thread will block.  This will cause not only** the requesting client to block but every other database client as** well.  It is possible to enhance the code below so that lock** contention will cause the message to be placed back on the top of** the queue to be tried again later.  But such enhanced processing is** not included here, in order to keep the example simple.**** This example code assumes the use of pthreads.  Pthreads** implementations are available for windows.  (See, for example** http://sourceware.org/pthreads-win32/announcement.html.)  Or, you** can translate the locking and thread synchronization code to use** windows primitives easily enough.  The details are left as an** exercise to the reader.****** Restrictions Associated With SQLITE_ENABLE_MEMORY_MANAGEMENT ******** If you compile with SQLITE_ENABLE_MEMORY_MANAGEMENT defined, then** SQLite includes code that tracks how much memory is being used by** each thread.  These memory counts can become confused if memory** is allocated by one thread and then freed by another.  For that** reason, when SQLITE_ENABLE_MEMORY_MANAGEMENT is used, all operations** that might allocate or free memory should be performanced in the same** thread that originally created the database connection.  In that case,** many of the operations that are listed above as safe to be performed** in separate threads would need to be sent over to the server to be** done there.  If SQLITE_ENABLE_MEMORY_MANAGEMENT is defined, then** the following functions can be used safely from different threads** without messing up the allocation counts:****       sqlite3_bind_parameter_name**       sqlite3_bind_parameter_index**       sqlite3_changes**       sqlite3_column_blob**       sqlite3_column_count**       sqlite3_complete**       sqlite3_data_count**       sqlite3_db_handle**       sqlite3_errcode**       sqlite3_errmsg**       sqlite3_last_insert_rowid**       sqlite3_total_changes**** The remaining functions are not thread-safe when memory management** is enabled.  So one would have to define some new interface routines** along the following lines:****       sqlite3_client_bind_***       sqlite3_client_clear_bindings**       sqlite3_client_column_***       sqlite3_client_create_collation**       sqlite3_client_create_function**       sqlite3_client_transfer_bindings**** The example code in this file is intended for use with memory** management turned off.  So the implementation of these additional** client interfaces is left as an exercise to the reader.**** It may seem surprising to the reader that the list of safe functions** above does not include things like sqlite3_bind_int() or** sqlite3_column_int().  But those routines might, in fact, allocate** or deallocate memory.  In the case of sqlite3_bind_int(), if the** parameter was previously bound to a string that string might need** to be deallocated before the new integer value is inserted.  In** the case of sqlite3_column_int(), the value of the column might be** a UTF-16 string which will need to be converted to UTF-8 then into** an integer.*//*** Only compile the code in this file on UNIX with a THREADSAFE build** and only if the SQLITE_SERVER macro is defined.*/#if defined(SQLITE_SERVER) && !defined(SQLITE_OMIT_SHARED_CACHE)#if defined(OS_UNIX) && OS_UNIX && defined(THREADSAFE) && THREADSAFE/*** We require only pthreads and the public interface of SQLite.*/#include <pthread.h>#include "sqlite3.h"/*** Messages are passed from client to server and back again as ** instances of the following structure.*/typedef struct SqlMessage SqlMessage;struct SqlMessage {  int op;                      /* Opcode for the message */  sqlite3 *pDb;                /* The SQLite connection */  sqlite3_stmt *pStmt;         /* A specific statement */  int errCode;                 /* Error code returned */  const char *zIn;             /* Input filename or SQL statement */  int nByte;                   /* Size of the zIn parameter for prepare() */  const char *zOut;            /* Tail of the SQL statement */  SqlMessage *pNext;           /* Next message in the queue */  SqlMessage *pPrev;           /* Previous message in the queue */  pthread_mutex_t clientMutex; /* Hold this mutex to access the message */  pthread_cond_t clientWakeup; /* Signal to wake up the client */};/*** Legal values for SqlMessage.op*/#define MSG_Open       1  /* sqlite3_open(zIn, &pDb) */#define MSG_Prepare    2  /* sqlite3_prepare(pDb, zIn, nByte, &pStmt, &zOut) */#define MSG_Step       3  /* sqlite3_step(pStmt) */#define MSG_Reset      4  /* sqlite3_reset(pStmt) */#define MSG_Finalize   5  /* sqlite3_finalize(pStmt) */#define MSG_Close      6  /* sqlite3_close(pDb) */#define MSG_Done       7  /* Server has finished with this message *//*** State information about the server is stored in a static variable

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -