【原创】sqlite线程安全实验【chad20130201】

【原创】sqlite线程安全实验【chad20130201】,第1张

概述【原创】sqlite线程安全实验【chad20130201】 编译sqlite时使用默认配置,启用了线程安全设置。 实验程序如下: int Query_db( char* db_file_name ){ printf("in %s\n",__FUNCTION__); int ret; sqlite3_stmt *pstmt = NULL; char 【原创】sqlite线程安全实验【chad20130201】

编译sqlite时使用默认配置,启用了线程安全设置。

实验程序如下:

int query_db( char* db_file_name ){    printf("in %s\n",__FUNCTION__);    int    ret;    sqlite3_stmt    *pstmt = NulL;    char    *errMsg = NulL;    char    *sql = "SELECT * FROM MonthFreezetable WHERE ID<500;";//查询表中有多少列    int    ID;    STRUCT_TEST1    test_struct1;    STRUCT_TEST2    test_struct2;    memset(&test_struct1,0,sizeof(test_struct1));    memset(&test_struct2,sizeof(test_struct2));    ret = sqlite3_prepare(pdb,sql,strlen(sql),&pstmt,&errMsg);     if( ret != sqlITE_OK )    {        printf("error code :%d,reason:%s\n",ret,errMsg);        sqlite3_free( errMsg );        return -1;    }/*这一部分程序有问题*/    while( 1 )    {        ret = sqlite3_step(pstmt);        if( ret != sqlITE_ROW )        {    break; }        ID = sqlite3_column_int(pstmt,0);        printf("ID = %d ",ID);        usleep(10000);    }    sqlite3_finalize( pstmt ); //把刚才分配的内容析构掉    sqlite3_reset( pstmt );    return 0;}int    UpdateBlobData(char *db_file_name){    printf("in %s\n",__FUNCTION__);    int    ret;    sqlite3_stmt    *pstmt = NulL;    char    *errMsg = NulL;    char    sql[1023];// = "UPDATE MonthFreezetable SET TimeScale=datetime(),ForwardPowerInd=:forw WHERE ID>0;";    int        index1,index2;    char    *timebuf="2010-11-11";    clock_t starttime,endtime;    double totaltime;    starttime = clock();    printf("start update the db \n");    int i ;    for(i=0;i<441;i++){        printf("%10d",i);        //timebuf = Now();        //printf("Now:%s",timebuf);        sprintf(sql,"UPDATE MonthFreezetable SET TimeScale=datetime(),ForwardPowerInd=:forw WHERE ID=%d;",i);        ret = sqlite3_prepare(pdb,&errMsg);//预编译        if( ret != sqlITE_OK )        {            printf("error code :%d,errMsg);            sqlite3_free( errMsg );            return -1;        }        index2 = sqlite3_bind_parameter_index( pstmt,":forw" );//生成索引         ret = sqlite3_bind_blob(pstmt,index2,10,sqlITE_STATIC);//绑定数据流         if( ret != sqlITE_OK )        {            printf("the sqlite3_bind_blob error!\n");            printf("error code :%d \n",ret);            return -1;        }    restep:        sqlite3_busy_timeout(pdb,1000);        ret = sqlite3_step(pstmt);//执行        if( ret != sqlITE_DONE )        {            if( ret == sqlITE_BUSY ){//sqlITE_BUSY                printf("step timeout!\n");                goto restep;            }            printf("the sqlite3_step error!\n");            printf("error code :%d \n",ret);            return -1;        }    }    printf("end update the db \n");    endtime = clock();    totaltime = (double)( (endtime - starttime)/(double)CLOCKS_PER_SEC );    printf("the total time = %f s\n",totaltime);    printf("the step time = %f ms\n",(totaltime*1000)/(12*2041));    sqlite3_finalize( pstmt ); //把刚才分配的内容析构掉    sqlite3_reset( pstmt );    return 0;}

实验1:两个线程(进程同时进行数据查询 *** 作!)

int main(voID){    int ret;    ret = Create_db( "/home/terminal.db" );    if(ret < 0)    {        return -1;    }    int pID = fork();    if(pID < 0) {        perror("fork error!\n");        return 0;    }    if(pID==0){        printf("the child pross!\n");        ret = query_db( "/home/terminal.db" );        if(ret < 0)        {            return -1;        }        printf("child sleep 5!\n");        sleep(5);    }else{        printf("the father pross!\n");        ret = query_db( "/home/terminal.db" );        if(ret < 0)        {            return -1;        }        sleep(5);        printf("father sleep 5!\n");    }    sqlite3_close(pdb);    return 0;}

打印结果如下所示:(示例) @H_826_301@ @H_826_301@ 如上图红色部分所示,两个进程分别交叉打印查询结果,这说明:sqlite3多线程查询互不影响,是线程安全的。@H_404_304@ @H_826_301@ 实验2:一个进程进行查询,一个进程进行更新 *** 作,代码片段如下:

int pID = fork();    if(pID < 0) {        perror("fork error!\n");        return 0;    }    if(pID==0){        printf("the child pross!\n");        ret = UpdateBlobData( "/home/terminal.db" );        if(ret < 0)        {            return -1;        }        printf("child sleep 5!\n");        sleep(5);    }else{        printf("the father pross!\n");        ret = query_db( "/home/terminal.db" );        if(ret < 0)        {            return -1;        }        sleep(5);        printf("father sleep 5!\n");    }

执行结果如下: @H_826_301@ @H_826_301@ 结果如上,程序先运行了父进程,但是父进程的sqlite3_step(pstmt)返回了超时,同时,子进程的查询 *** 作正确执行。待子进程查询完毕退出后父进程的更新 *** 作才继续进行。这说明:sqlite的线程安全是有效的,当有数据更新 *** 作时,更新 *** 作是安全的互斥的,所以,编程时不需要专门编写线程锁程序对数据库 *** 作进行保护。@H_404_304@

由于sqlite仅仅提供了粒度很粗的数据锁,如读写锁,因此在每次加锁 *** 作中都会有大量的数据被锁住,即使仅有极小部分的数据会被访问。换句话说,我们可以认为sqlite只是提供了表级锁,没有提供行级锁。在这种同步机制下,并发性能很难高效。

总结

以上是内存溢出为你收集整理的【原创】sqlite线程安全实验【chad20130201】全部内容,希望文章能够帮你解决【原创】sqlite线程安全实验【chad20130201】所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1170280.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存