免费注册 查看新帖 |

Chinaunix

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

关于在线程中建立数据库连接的问题(大家进来看看) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-12-18 11:50 |只看该作者 |倒序浏览

我的程序中三个线程,均含数据库操作;
应该怎样让他们的连接独立呢?
以下是我的部分代码:

typedef struct _recCmppApi
{   
        pthread_t  SearchtableSubmit;
        pthread_t  SearchMessageInfo;
}RecCmppApi;

EXEC SQL INCLUDE SQLCA;

EXEC SQL BEGIN DECLARE SECTION;
sql_context BLUEHUT;
EXEC SQL END DECLARE SECTION;

void sql_cnn()                 //数据库连接
{
        EXEC SQL BEGIN DECLARE SECTION;
        VARCHAR  username[20];       
        VARCHAR  password[20];
        int intfilename=0;
        EXEC SQL END DECLARE SECTION;
       
        strcpy((char *)username.arr,"SCOTT";
        username.len = strlen((char *)username.arr);
        strcpy((char *)password.arr,"TIGER";
        password.len = strlen((char *)password.arr);
        EXEC SQL WHENEVER SQLERROR STOP;

        EXEC SQL CONTEXT ALLOCATE :BLUEHUT;
        EXEC SQL CONTEXT USE :BLUEHUT;
        EXEC SQL CONNECT :username IDENTIFIED BY :password;

        if(sqlca.sqlcode!=0)
        {
        printf("连接失败 sqlcode=[%d]\n",sqlca.sqlcode);
        return(-1);
        }
        printf("Oracle Connect Sucess!!!\n";
        printf("sqlca.sqlcode =[%d]\n",sqlca.sqlcode);
        printf("intfilename =[%d]\n",intfilename);
}

void *searchtablesubmit()
{
        sql_cnn();
        while(1)
        {
               
                printf("2222222222222\n";
                sleep(1);
        }
}


void *searchmessageinfo()
{
        sql_cnn();
        while(1)
        {
               
                printf("1111111111111111\n";
                sleep(1);
                }

}

//主函数
int main(int argc ,char *argv[])
{
    int  nRet;
    int memlen=0;
   
    //初始化
    nRet = 0;
   
    //线程一
        nRet=pthread_creade(&grecCmppApi.SearchtableSubmit,NULL,searchtablesubmit,NULL);
        printf("\t succ to create searchtablesubmit thread \n\n";
   //线程二
        nRet=pthread_creade(&grecCmppApi.SearchMessageInfo,NULL,searchmessageinfo,NULL);
        printf("\t succ to create searchmessageinfo thread \n\n";

   nRet = pthread_join(grecCmppApi.SearchtableSubmit,NULL);

   nRet = pthread_join(grecCmppApi.SearchMessageInfo,NULL);

    return 0;

}

论坛徽章:
0
2 [报告]
发表于 2003-12-18 14:32 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

连接独立具体指什么?

论坛徽章:
0
3 [报告]
发表于 2003-12-18 17:36 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

是不是可以为没个线程分配独立的堆内存

防止内存出错?

论坛徽章:
0
4 [报告]
发表于 2003-12-18 18:06 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

http://bbs.chinaunix.net/forum/23/20031216/223942.html

我发的帖子,居然没人顶一下,看来大家还对多线程访问数据库没热情。

论坛徽章:
0
5 [报告]
发表于 2003-12-18 18:14 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

原帖由 "bjf" 发表:
http://bbs.chinaunix.net/forum/23/20031216/223942.html

我发的帖子,居然没人顶一下,看来大家还对多线程访问数据库没热情。


强烈支持
这真是我所需要的
我先看看,如果有什么不明白的
再请教你了~
可以么?

论坛徽章:
0
6 [报告]
发表于 2003-12-19 09:10 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

如果我想在多线程使用互相独立的运行时上下文

是不是这样:
EXEC SQL BEGIN DECLARE SECTION;
sql_context context;
sql_context context1;
               .
               .
               .
               .
sql_context contextn;
EXEC SQL END DECLARE SECTION;
可不可以呀?

论坛徽章:
0
7 [报告]
发表于 2003-12-19 09:50 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

多线程访问数据库的时候,我觉得关键的一点就是在每条SQL语句执行前都需要指定context!

论坛徽章:
0
8 [报告]
发表于 2003-12-19 10:25 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

每个线程都要分配自己的连接池,并且还要为每个线程分配一定的内存(默认内存可能不够用,容易发生 core现象),在线程中如果要调用
嵌入sql 则需要指定各自线程的 context..

论坛徽章:
0
9 [报告]
发表于 2003-12-19 10:32 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

我的程序又出内存错误了?
我把代码发上来大家帮我看看吧~

论坛徽章:
0
10 [报告]
发表于 2003-12-19 10:33 |只看该作者

关于在线程中建立数据库连接的问题(大家进来看看)

#include "stdafx.h"
#include "test1.h"

static RecCmppApi grecCmppApi;
static int gnExitAllThread=0;

EXEC SQL INCLUDE SQLCA;

#ifdef WIN32

int pthread_creade(pthread_t *thread,const pthread_attr_t *attr,void *pProcAddr,const void *arg)
{
        DWORD dw;
        *thread=CreateThread(NULL,10000,(LPTHREAD_START_ROUTINE)pProcAddr,(LPVOID)arg,0,&dw);
        if(*thread!=NULL)
                return 0;
        return -1;
}

//等待线程结束
int pthread_join(pthread_t thread,void *value_ptr)
{
    WaitForSingleObject( thread, INFINITE );
    CloseHandle(thread);
    return 0;
}

#endif

/*错误处理函数*/
sql_error(char *msg)
{
        printf("\n你的操作不当,程序将重新开始运行\n以下是出错信息:";
        printf("\n%s,%ld,%s\n", msg,sqlca.sqlcode,(char *)sqlca.sqlerrm.sqlerrmc);
        EXEC SQL ROLLBACK RELEASE;
}

void conn_deliver()
{
        EXEC SQL BEGIN DECLARE SECTION;
        sql_context envtext1;
        VARCHAR  username[20];        //声明宿主变量
        VARCHAR  password[20];
        VARCHAR  dbname[20];
        EXEC SQL END DECLARE SECTION;

        sleep(6);

        strcpy((char *)username.arr,"SCOTT";
        username.len = strlen((char *)username.arr);
        strcpy((char *)password.arr,"TIGER";
        password.len = strlen((char *)password.arr);
        //EXEC SQL WHENEVER SQLERROR STOP;        //隐式异常
        dbname.len = strlen((char *)dbname.arr);
        strcpy((char *)dbname.arr,"BLUEHUT";

        EXEC SQL ENABLE THREADS;
        EXEC SQL CONTEXT ALLOCATE :envtext1;
        EXEC SQL CONTEXT USE :envtext1;
        EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbname;
        if(sqlca.sqlcode!=0)
        {
                printf("连接失败 sqlcode=[%d]\n",sqlca.sqlcode);
        }
        printf("Oracle Connect Sucess!!!\n";
        printf("sqlca.sqlcode =[%d]\n",sqlca.sqlcode);
        deliver(envtext1);
}

void deliver(envtext1)
{
        EXEC SQL BEGIN DECLARE SECTION;
        //sql_context envtext1;
        char temp_servercode[6];
        char temp_srcmobile[20];
        char temp_id[5];
        char getdeliver_sql[50];
        EXEC SQL END DECLARE SECTION;
       
        EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE ERROR: ";        //错误处理
        int total=0;
        while(1)
        {
                EXEC SQL CONTEXT USE :envtext1;
                strcpy(getdeliver_sql,"SELECT * FROM tempdeliver";
                EXEC SQL PREPARE getdeliver_s FROM :getdeliver_sql;
                EXEC SQL DECLARE cur_getdeliver CURSOR FOR getdeliver_s;        //定义游标
                EXEC SQL OPEN cur_getdeliver;

                printf("\t 启动收包进程\n\n";
               
                while(1)
                {
                        EXEC SQL FETCH cur_getdeliver INTO :temp_servercode,:temp_srcmobile,:temp_id;
                        sleep(1);
                        if( sqlca.sqlcode == 1403)
                        {
                                printf("没有新记录\n";
                                break;
                        }

                                EXEC SQL INSERT INTO deliver(servercode,srcmobile,id) VALUES(:temp_servercode,:temp_srcmobile,:temp_id);
                                strcpy(getdeliver_sql,"";
                                /*strcpy(getdeliver_sql,"delete tempdeliver where id=");
                                strcat(getdeliver_sql,temp_id);
                                EXEC SQL EXECUTE IMMEDIATE :getdeliver_sql;*/
                                EXEC SQL COMMIT;
                                total=total+1;
                                printf("\t 收取到的第%d条 mo 信息为: \n",total);
                                printf("\t servercode=%s,srcmobile=%s,id=%s \n",temp_servercode,temp_srcmobile,temp_id);

                       
                }
                EXEC SQL CLOSE cur_getdeliver;
                usleep(1);
        }
        EXEC SQL CONTEXT FREE :envtext1;
}

void conn_submit()
{
        EXEC SQL BEGIN DECLARE SECTION;
        sql_context envtext2;
        varchar username[20];
        varchar password[20];
        varchar dbname[20];
        EXEC SQL END DECLARE SECTION;

        strcpy((char *)username.arr,"SCOTT");
        username.len=strlen((char *)username.arr);
        strcpy((char *)password.arr,"TIGER");
        password.len=strlen((char *)password.arr);
        strcpy((char *)dbname.arr,"BLUEHUT");
        dbname.len=strlen((char *)dbname.arr);

        EXEC SQL ENABLE THREADS;
        EXEC SQL CONTEXT ALLOCATE :envtext2;
        EXEC SQL CONTEXT USE :envtext2;
        EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbname;
        if(sqlca.sqlcode!=0)
        {
                printf("连接失败 sqlcode=[%d]\n",sqlca.sqlcode);
        }
        printf("Oracle connect Sucess!!\n");
        printf("sqlca.sqlcode=[%d]\n",sqlca.sqlcode);
        submit(envtext2);
}

void submit(envtext2)
{
        EXEC SQL BEGIN DECLARE SECTION;
        char id[5];
        char servercode[6];
        char objmobile[20];
        char srcmobile[20];
        char searchtablesubmit_sql[50];
        EXEC SQL END DECLARE SECTION;

        while(1)
        {
                EXEC SQL CONTEXT USE :envtext2;
                strcpy(searchtablesubmit_sql,"SELECT * FROM submit");

                EXEC SQL PREPARE searchtablesubmit_s FROM :searchtablesubmit_sql;
                EXEC SQL DECLARE cur_searchtablesubmit CURSOR FOR searchtablesubmit_s;        //定义游标
                EXEC SQL OPEN cur_searchtablesubmit;
                printf("\t 启动发包进程 \n\n");
                sleep(1);
                while(1)
                {
                        EXEC SQL FETCH cur_searchtablesubmit INTO :id,:servercode,:srcmobile,bjmobile;
                        sleep(1);
                        if( sqlca.sqlcode == 1403)
                        {
                                break;
                        }
                        EXEC SQL INSERT INTO hissubmit(id,servercode,srcmobile,objmobile) VALUES(:id,:servercode,bjmobile,:srcmobile);
                        /*strcpy(searchtablesubmit_sql,"DELETE FROM submit WHERE id=");
                        strcat(searchtablesubmit_sql,id);
                        EXEC SQL EXECUTE IMMEDIATE :searchtablesubmit_sql;*/
                        EXEC SQL COMMIT;
                        printf("\t 发送信息内容: \n");
                        printf("\t servercode=%s,srcmobile=%s,id=%s \n",servercode,srcmobile,id);
                }
                EXEC SQL CLOSE cur_searchtablesubmit;

                usleep(1);
        }
        //FreeConText(envtext2);
        EXEC SQL CONTEXT FREE :envtext2;
}

//主函数
int main(int argc ,char *argv[])
{
    int  nRet;

   
    //初始化
    nRet = 0;
//    vMarkSign();                                                                        //初始化中断信息



        //启动模拟取缓存中mo

        nRet=pthread_creade(&grecCmppApi.HGetDeliver,NULL,conn_deliver,NULL);
        printf("\t succ to create getdeliver thread \n\n");

        //启动查找需要发送的mt信息
        nRet=pthread_creade(&grecCmppApi.SearchtableSubmit,NULL,conn_submit,NULL);
        printf("\t succ to create searchtablesubmit thread \n\n");

        //启动需要发送定制业务信息
//        nRet=pthread_creade(&grecCmppApi.SearchMessageInfo,NULL,searchmessageinfo,NULL);
//        printf("\t succ to create searchmessageinfo thread \n\n");

    //中断处理函数
   signal(SIGINT,(void *)vKillThread);

    //等待线程结束
   nRet = pthread_join(grecCmppApi.HGetDeliver,NULL);

   nRet = pthread_join(grecCmppApi.SearchtableSubmit,NULL);

//   nRet = pthread_join(grecCmppApi.SearchMessageInfo,NULL);

    return 0;

}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP