Thank you very much for your post Just after I post the last code I know the concept of "reentrant" and "thread-safety".
And you should notice the wrong usage of printf() in signal handle func. ^_^ So I re-writed the code and re-test. And the problem is still in someplace. So I re-post the question. Again, I appreciate your answer, :) Pavel Ivanov-2 wrote: > > Why do you re-post your code as if it's another question not related > to previous one (along with the answer)? > >> does it mean that the sqlite3's C-api isn't reentrant or thread-safety? > > If SQLite is compiled with SQLITE_THREADSAFE = 1 or 2 then API is > thread-safe (with some limitations when it's 2), if SQLITE_THREADSAFE > = 0 then API is not thread-safe. But in both cases I have a doubt > about signal-safety and also API is not re-entrant for sure except for > some specially designed functions. > > Pavel > > On Thu, Jul 9, 2009 at 3:52 AM, liubin liu<7101...@sina.com> wrote: >> >> does it mean that the sqlite3's C-api isn't reentrant or thread-safety? >> >> >> ____________________________________________________________ >> >> >> #include <stdio.h> // for printf() >> #include <signal.h> // for signal() >> #include <unistd.h> // for alarm() >> #include <stdlib.h> // for system() >> #include <pthread.h> // for pthread_create() >> #include <sqlite3.h> // for sqlite3_*** >> >> >> >> sqlite3 *db = NULL; >> >> int timer_handle_mark1 = 0; >> int timer_handle_mark2 = 9; >> >> >> >> pthread_t trd1; >> >> void trd1_task ( void ); >> >> >> >> int sqlite3_helper_create_db (void); >> >> int sqlite3_helper_insert_data (void); >> >> // psf - prepare, step, finalize >> int sqlite3_helper_get_data_psf_from_tb1 ( int id ); >> >> void timer_handler() >> { >> int ret = -1; >> int i = 9; >> >> char *query_format2 = "SELECT * FROM ts2 WHERE id=%d;"; >> char *query_string = NULL; >> >> >> sqlite3_stmt *p_stmt = NULL; >> >> timer_handle_mark2 = 0; >> query_string = sqlite3_mprintf ( query_format2, i%500 ); >> timer_handle_mark1++; >> >> timer_handle_mark2 = 1; >> ret = sqlite3_prepare_v2 ( db, query_string, -1, &p_stmt, NULL ); >> timer_handle_mark1++; >> >> timer_handle_mark2 = 2; >> ret = sqlite3_step ( p_stmt ); >> timer_handle_mark1++; >> >> //if ( SQLITE_ROW == ret ) >> // printf ( "# IN timer_handler(), id: %d, length: %d\n", >> sqlite3_column_int( p_stmt, 0 ), sqlite3_column_int( p_stmt, 1 ) ); >> >> timer_handle_mark2 = 3; >> sqlite3_finalize ( p_stmt ); >> timer_handle_mark1++; >> >> >> alarm(1); >> } >> >> int inittimer() >> { >> signal ( SIGALRM, timer_handler ); >> alarm(1); >> return 0; >> } >> >> void trd1_task ( void ) >> { >> sleep (30); >> printf ( "# IN thread 1, after 30 seconds, timer_handle_mark1: %d, >> timer_handle_mark2: %d\n", timer_handle_mark1, timer_handle_mark2 ); >> sleep (50); >> printf ( "# IN thread 1, after 50 seconds, timer_handle_mark1: %d, >> timer_handle_mark2: %d\n", timer_handle_mark1, timer_handle_mark2 ); >> } >> >> >> >> int main ( void ) >> { >> int ret = -1; >> int i = 0; >> >> ret = pthread_create ( &trd1, 0, (void *)trd1_task, 0 ); >> >> ret = sqlite3_open ( "testsignal.db", &db ); >> >> sqlite3_helper_create_db (); >> >> sqlite3_helper_insert_data (); >> >> ret = inittimer(); >> >> for ( i=0; ; i++ ) >> ret = sqlite3_helper_get_data_psf_from_tb1 ( i ); >> >> ret = sqlite3_close ( db ); >> >> system ( "sqlite3 testsignal.db \"SELECT COUNT(*) FROM ts1;\"" ); >> >> return 0; >> } >> >> >> int sqlite3_helper_create_db (void) >> { >> int ret = -1; >> char *cr_tb1 = "CREATE TABLE ts1 (id INTEGER PRIMARY KEY, length >> INTEGER, data CHAR(50));"; >> char *cr_tb2 = "CREATE TABLE ts2 (id INTEGER PRIMARY KEY, length >> INTEGER, data CHAR(50));"; >> >> ret = sqlite3_exec ( db, cr_tb1, NULL, NULL, NULL ); >> //printf ( "ret: %d\n", ret ); >> ret = sqlite3_exec ( db, cr_tb2, NULL, NULL, NULL ); >> //printf ( "ret: %d\n", ret ); >> if ( SQLITE_OK == ret ) >> printf ( "# IN main(), create db file, SUCCESS!\n" ); >> >> >> return 0; >> } >> >> >> int sqlite3_helper_insert_data (void) >> { >> int ret = -1; >> int i = 0; >> >> sqlite3_stmt *p_stmt = NULL; >> >> >> char *sql_format1 = "INSERT OR REPLACE INTO ts1 (id, length, data) >> VALUES (%d, %d, %Q);"; >> char *sql_format2 = "INSERT OR REPLACE INTO ts2 (id, length, data) >> VALUES (%d, %d, %Q);"; >> char *sql = NULL; >> >> >> ret = sqlite3_exec ( db, "BEGIN", NULL, NULL, NULL ); >> for ( i=0; i<500; i++ ) >> { >> sql = sqlite3_mprintf ( sql_format1, i, i%10, >> "datadatadatadatadatadatadatadatadatadatadata" ); >> ret = sqlite3_prepare_v2 ( db, sql, -1, &p_stmt, NULL ); >> ret = sqlite3_step ( p_stmt ); >> sqlite3_free ( sql ); >> ret = sqlite3_finalize ( p_stmt ); >> >> sql = sqlite3_mprintf ( sql_format2, i, i%10, >> "datadatadatadatadatadatadatadatadatadatadata" ); >> ret = sqlite3_prepare_v2 ( db, sql, -1, &p_stmt, NULL ); >> ret = sqlite3_step ( p_stmt ); >> sqlite3_free ( sql ); >> ret = sqlite3_finalize ( p_stmt ); >> } >> ret = sqlite3_exec ( db, "COMMIT", NULL, NULL, NULL ); >> if ( SQLITE_OK == ret ) >> printf ( "# IN main(), insert data, SUCCESS!\n" ); >> >> return 0; >> } >> >> >> int sqlite3_helper_get_data_gt_from_tb1 ( int id ) >> { >> int ret = -1; >> >> >> char *query_format1 = "SELECT * FROM ts1 WHERE id=%d;"; >> char *query_string = NULL; >> >> char **resultp = NULL; >> int row = 0; >> int column = 0; >> char *errmsg = NULL; >> char **tmp_str = NULL; >> >> query_string = sqlite3_mprintf ( query_format1, id%500 ); >> ret = sqlite3_get_table ( db, query_string, &resultp, &row, &column, >> &errmsg ); >> if ( SQLITE_OK == ret ) >> { >> //printf ( "sqlite3_get_table() success!\n" ); >> tmp_str = resultp + column; >> printf ( "# IN main(), id: %d, length: %d\n", atoi(tmp_str[0]), >> atoi(tmp_str[1]) ); >> } >> sqlite3_free ( query_string ); >> sqlite3_free_table ( resultp ); >> >> return 0; >> } >> >> >> int sqlite3_helper_get_data_psf_from_tb1 ( int id ) >> { >> int ret = -1; >> >> sqlite3_stmt *p_stmt = NULL; >> >> >> char *query_format1 = "SELECT * FROM ts1 WHERE id=%d;"; >> char *query_string = NULL; >> >> query_string = sqlite3_mprintf ( query_format1, id%500 ); >> ret = sqlite3_prepare_v2 ( db, query_string, -1, &p_stmt, NULL ); >> ret = sqlite3_step ( p_stmt ); >> //if ( SQLITE_ROW == ret ) >> // printf ( "# IN main(), id: %d, length: %d; timer_handle_mark1: >> %d\n", sqlite3_column_int( p_stmt, 0 ), sqlite3_column_int( p_stmt, 1 ), >> timer_handle_mark1 ); >> sqlite3_finalize ( p_stmt ); >> >> return 0; >> } >> >> >> -- >> View this message in context: >> http://www.nabble.com/is-the-sqlite3%27s-C-api-used-in-thread-safety-mode---or-non-reentrant--tp24405739p24405739.html >> Sent from the SQLite mailing list archive at Nabble.com. >> >> _______________________________________________ >> sqlite-users mailing list >> sqlite-users@sqlite.org >> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users >> > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > > -- View this message in context: http://www.nabble.com/is-the-sqlite3%27s-C-api-used-in-thread-safety-mode---or-non-reentrant--tp24405739p24420186.html Sent from the SQLite mailing list archive at Nabble.com. _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users