免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6475 | 回复: 23
打印 上一主题 下一主题

ESQL 采用多线程操作数据库,只有第一个线程可以操作成功? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-07 10:49 |只看该作者 |倒序浏览
各位大侠,
        我在Solaris下编写 ESQL/C for Sybase 的程序,采用多线程方式,在线程里面建立数据库连接,结果只有第一个线程可以成功访问到数据库,第二个线程就读不出来数据。。。。。但也没有报错。。。

        请各位帮忙,谢谢!

程序代码如下:



void * sybase_thread( void *arg )
{
        int        iRet ;

        exec sql include sqlca ;
        exec sql begin declare section;
                                int                iCount;
                char        hello_world[28];

                                char        tmp_line_code[1+2];
        exec sql end declare section;

                /*
        exec sql whenever sqlerror goto exit_MulThr ;
        exec sql whenever sqlwarning goto exit_MulThr ;
        exec sql whenever not found continue ;
                */

/*
**  protect acquiring cs_objects resources
*/

                memset( tmp_line_code, '\0', sizeof(tmp_line_code) );
                strcpy( tmp_line_code, (char * )arg );

                cout << "tmp_line_code = " << tmp_line_code << endl;
                cout << tmp_line_code << tmp_line_code << endl;
       
        pthread_mutex_lock(&gMutexCode);
        exec sql connect "sa" identified by "sybase" using "server";
        pthread_mutex_unlock(&gMutexCode);

                /*
        exec sql select 'Hello Sybase World' into :hello_world;
                */

                iCount = 0;
                EXEC SQL SELECT count(*) INTO :iCount
                        FROM station_code
                        WHERE line_id = '03';
                printSQLMsg();
                iRet = SQLCODE;
               
                cout << pthread_self() << ", iCount = " << iCount << endl;

        // printf("[%d]: %s\n", pthread_self(), hello_world);

                /*
        exec sql disconnect all ;
                */
        return( 0 ) ;
exit_MulThr:
        printf("[%d]: Error: %d %s \n", pthread_self(),sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);
        return( 0 );
}




int main()
{
    for (i = 0 ; i < 2 ; i++ ) {
                pthread_create( &stid[i], NULL, sybase_thread, (void *)"3" );
                //pthread_create( &stid[1], NULL, DataInitByLine, (void *)"04" );
        }
     for (i = 0 ; i < 2 ; i++ )
                pthread_join( stid[i],  NULL ) ;

    return( 0 );

}


输出结果:


tmp_line_code = 3
33
tmp_line_code = 3
33
6, iCount = 0
5, iCount = 90

只有线程号为 5 的线程查询成功了。。。。线程号为 6 的线程没有访问到数据库??
在多台Sun的服务器上试了多次都是这样。。。。

请各位指教!!谢谢了!!

论坛徽章:
0
2 [报告]
发表于 2007-03-07 14:14 |只看该作者
请各位多多指教啊

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
3 [报告]
发表于 2007-03-07 15:18 |只看该作者
应该是pthread_mutex_lock 互斥的问题,导致connect 有问题,

gMutexCode 变量定义的应该没问题吧,全局的?

论坛徽章:
0
4 [报告]
发表于 2007-03-07 17:51 |只看该作者

这里互斥锁的目的是什么?

pthread_mutex_lock(&gMutexCode);
        exec sql connect "sa" identified by "sybase" using "server";
        pthread_mutex_unlock(&gMutexCode);

论坛徽章:
0
5 [报告]
发表于 2007-03-08 15:24 |只看该作者
原帖由 chuxu 于 2007-3-7 15:18 发表
应该是pthread_mutex_lock 互斥的问题,导致connect 有问题,

gMutexCode 变量定义的应该没问题吧,全局的?


谢谢chuxu兄指教,gMutexCode 定义得是全局变量,在子线程中得连接数据库前进行了加锁,之后进行了解锁,同时,在断开数据库前也进行了加锁,断开数据库后也进行了解锁,还是有同样问题,创建的多个线程不能都全部成功访问数据库。。。。。

调整后得代码如下,请帮忙看看:


void * sybase_thread( void *arg )
{
        int        iRet ;

        exec sql include sqlca ;
        exec sql begin declare section;
                                int                iCount;
                char        hello_world[28];

                                char        tmp_line_code[1+2];
                                int                iThreadID;
                                char        tmp_cnct_name[1+6];
        exec sql end declare section;

                /*
        exec sql whenever sqlerror goto exit_MulThr ;
        exec sql whenever sqlwarning goto exit_MulThr ;
        exec sql whenever not found continue ;
                */

/*
**  protect acquiring cs_objects resources
*/

                memset( tmp_line_code, '\0', sizeof(tmp_line_code) );
                strcpy( tmp_line_code, (char * )arg );

                // cout << "tmp_line_code = " << tmp_line_code << endl;
                cout << tmp_line_code << tmp_line_code << endl;

                iThreadID = thr_self();

                cout << "iThreadID=" << iThreadID << endl;

                memset( tmp_cnct_name, '\0', sizeof(tmp_cnct_name) );
                sprintf( tmp_cnct_name, "DBCnct%d", iThreadID );
                // sprintf( tmp_cnct_name, "ABC%d", iThreadID );

        pthread_mutex_lock(&gMutexCode);
        exec sql connect "sa" identified by "sybase" using "server" at :tmp_cnct_name;

                /*
        exec sql select 'Hello Sybase World' into :hello_world;
                */

                cout << getTime() << "Connect database " << tmp_cnct_name << " successful." << endl;

                EXEC SQL SET connection :tmp_cnct_name;
                printSQLMsg();
                if( SQLCODE != 0 ) {
                        cout << getTime() << "set connection " << tmp_cnct_name << " failed." << endl;
                }
                cout << getTime() << "set connection " << tmp_cnct_name << " successful." << endl;

        pthread_mutex_unlock(&gMutexCode);

                // sleep(20);

                iCount = 0;
                /* EXEC SQL at :tmp_cnct_name SELECT count(*) INTO :iCount */
                EXEC SQL at DBCnct5 SELECT count(*) INTO :iCount
                        FROM station_code
                        WHERE line_id = '03';
                printSQLMsg();
                iRet = SQLCODE;
               
                cout << pthread_self() << ", iCount = " << iCount << endl;

        // printf("[%d]: %s\n", pthread_self(), hello_world);

                /*
        exec sql disconnect all ;
                */

                //pthread_mutex_lock(&gMutexCode);

                EXEC SQL SET connection DEFAULT;
                printSQLMsg();
                if( SQLCODE != 0 ) {
                        cout << getTime() << "SET connection DEFAULT " << tmp_cnct_name << " failed." << endl;
                }
                cout << getTime() << "SET connection DEFAULT " << tmp_cnct_name << " successful." << endl;

                EXEC SQL disconnect :tmp_cnct_name;
                printSQLMsg();
                if( SQLCODE != 0 ) {
                        cout << getTime() << "disconnect Database " << tmp_cnct_name << " failed." << endl;
                }
                cout << getTime() << "disconnect Database " << tmp_cnct_name << " successful." << endl;

        //pthread_mutex_unlock(&gMutexCode);

        return( 0 ) ;

exit_MulThr:
        printf("[%d]: Error: %d %s \n", pthread_self(),sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);

        return( 0 );
}

谢谢!

论坛徽章:
0
6 [报告]
发表于 2007-03-08 15:31 |只看该作者
原帖由 camham 于 2007-3-7 17:51 发表
pthread_mutex_lock(&gMutexCode);
        exec sql connect "sa" identified by "sybase" using "server";
        pthread_mutex_unlock(&gMutexCode);


谢谢camham兄帮忙,之前如果不加锁、解锁,同时创建的多个线程在连接数据库时,程序就会core down,
加了锁之后就没有再core down了

论坛徽章:
0
7 [报告]
发表于 2007-03-08 17:47 |只看该作者
各位大侠多多指教啊。。。。

论坛徽章:
0
8 [报告]
发表于 2007-03-09 18:20 |只看该作者
顶顶

论坛徽章:
1
2017金鸡报晓
日期:2017-01-10 15:19:56
9 [报告]
发表于 2007-03-10 15:12 |只看该作者
这个程序我在redhat EL4的环境下试过,应该没有问题呀

论坛徽章:
0
10 [报告]
发表于 2007-03-12 08:11 |只看该作者
原帖由 chuxu 于 2007-3-10 15:12 发表
这个程序我在redhat EL4的环境下试过,应该没有问题呀



是不是我的编译和连接方法不对。。。老兄可以把您在readhat环境下的例子代码贴出来看看吗??

谢谢了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP