首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

多线程任务,执行过程中,线程挂起,过段时间后进程死掉解决方案

2012-03-11 
多线程任务,执行过程中,线程挂起,过段时间后进程死掉C/C++ codeclass TBindFWD{private:char CHANNELID[RO

多线程任务,执行过程中,线程挂起,过段时间后进程死掉

C/C++ code
class TBindFWD{    private:    char CHANNELID[ROWCOUNT][5];    char RATECODE[ROWCOUNT][5];    char FEEDID[ROWCOUNT][5];    char FEEDBID[ROWCOUNT][15];    char FEEDASK[ROWCOUNT][15];    char FEEDMID[ROWCOUNT][15];    char VALIDFEEDBID[ROWCOUNT][15];    char VALIDFEEDASK[ROWCOUNT][15];    char VALIDFEEDMID[ROWCOUNT][15];    char BIDDELTA[ROWCOUNT][15];    char ASKDELTA[ROWCOUNT][15];    char QUOTEBID[ROWCOUNT][15];    char QUOTEASK[ROWCOUNT][15];    char QUOTEMID[ROWCOUNT][15];    char VALIDQUOTEBID[ROWCOUNT][15];    char VALIDQUOTEASK[ROWCOUNT][15];    char VALIDQUOTEMID[ROWCOUNT][15];    char BIDVOLUME[ROWCOUNT][19];    char ASKVOLUME[ROWCOUNT][19];    char TRADEMARK[ROWCOUNT][2];    char RUNSTATE[ROWCOUNT][2];    char VALUEDATE[ROWCOUNT][9];    char QUOTEBASIS[ROWCOUNT][15];    char QUOTEHIGH[ROWCOUNT][15];    char QUOTELOW[ROWCOUNT][15];    char QUOTEOPEN[ROWCOUNT][15];    char QUOTECLOSE[ROWCOUNT][15];    char REFRESHCOUNT[ROWCOUNT][9];    //char REFRESHTIME[ROWCOUNT][19];    char TERMID[ROWCOUNT][5]; //    char SPOTBID[ROWCOUNT][15]; //    char SPOTASK[ROWCOUNT][15]; //    char SPOTMID[ROWCOUNT][15]; //    char MATURITYDATE[ROWCOUNT][9]; //    char CALCBID[ROWCOUNT][15]; //    char CALCASK[ROWCOUNT][15]; //    std::string sql;    sql::TBindDefine * bd;    int _rowcount;    std::map<string, void *> bdmap;    pricepub::TPriceFPQuoteItem item;    //std::string datetimestr;    public:    TBindFWD(std::string bdsql);    TBindFWD();    ~TBindFWD(){delete bd;};    int GetRowcount() { return _rowcount;};    std::string GetSQL() { return sql;};    sql::TBindDefine * GetBindDefine() { return bd;};    void AddItem(pricepub::TPriceFPQuoteItem item1);};//---------------------------------------TBindFWD::TBindFWD(std::string bdsql){    int fieldcount, pos;    fieldcount = 0;    pos = 0;    while (1)    {        pos = bdsql.find(":bind_", pos);        if (pos == std::string::npos)            break;        pos = pos + 6;        fieldcount ++;    }    //fieldcount --;    //std::cout << "FWD:fieldcount = " << fieldcount << std::endl;    bd = new sql::TBindDefine (fieldcount);    do {        int pos1, pos2;        pos1 = bdsql.find(":bind_");        if (pos1 == std::string::npos)            break;        pos2 = bdsql.find(' ', pos1+6);        if (pos2 == std::string::npos)        {            std::cout << "Error in SQL!" << std::endl;            lang::mstring mstr;            mstr << "Error in SQL!";            throw lang::Exception(mstr.str());;        }        do        {            char c = bdsql[pos2-1];            if (isalpha(c))                break;            else                pos2 = pos2 - 1;        } while (1);        std::string field = bdsql.substr(pos1+6, pos2-pos1-6);        field = lang::TCharSet::Upper(field);        if (!strcmp(field.c_str(), "CHANNELID"))        {            bd->AddField((char *)CHANNELID, 5);            bdmap["CHANNELID"] = (void *)(&(item.ChannelID));                    }          else if (!strcmp(field.c_str(), "RATECODE"))          {              bd->AddField((char *)RATECODE, 5);              bdmap["RATECODE"] = (void *)(&(item.RateCode));                      }          else if (!strcmp(field.c_str(), "FEEDID"))          {              bd->AddField((char *)FEEDID, 5);              bdmap["FEEDID"] = (void *)(&(item.FeedID));                      }        else if (!strcmp(field.c_str(), "FEEDBID"))          {              bd->AddField((char *)FEEDBID, 15);              bdmap["FEEDBID"] = (void *)(&(item.FeedBid));                      }        else if (!strcmp(field.c_str(), "FEEDASK"))          {              bd->AddField((char *)FEEDASK, 15);              bdmap["FEEDASK"] = (void *)(&(item.FeedAsk));                      }        else if (!strcmp(field.c_str(), "FEEDMID"))          {              bd->AddField((char *)FEEDMID, 15);              bdmap["FEEDMID"] = (void *)(&(item.FeedMid));                      }        else if (!strcmp(field.c_str(), "VALIDFEEDBID"))          {              bd->AddField((char *)VALIDFEEDBID, 15);              bdmap["VALIDFEEDBID"] = (void *)(&(item.ValidFeedBid));                      }        else if (!strcmp(field.c_str(), "VALIDFEEDASK"))          {              bd->AddField((char *)VALIDFEEDASK, 15);              bdmap["VALIDFEEDASK"] = (void *)(&(item.ValidFeedAsk));                      }        else if (!strcmp(field.c_str(), "VALIDFEEDMID"))          {              bd->AddField((char *)VALIDFEEDMID, 15);              bdmap["VALIDFEEDMID"] = (void *)(&(item.ValidFeedMid));          }        else if (!strcmp(field.c_str(), "BIDDELTA"))          {              bd->AddField((char *)BIDDELTA, 15);              bdmap["BIDDELTA"] = (void *)(&(item.BidDelta));                      }        else if (!strcmp(field.c_str(), "ASKDELTA"))          {              bd->AddField((char *)ASKDELTA, 15);              bdmap["ASKDELTA"] = (void *)(&(item.AskDelta));          }        else if (!strcmp(field.c_str(), "QUOTEBID"))          {              bd->AddField((char *)QUOTEBID, 15);              bdmap["QUOTEBID"] = (void *)(&(item.QuoteBid));          }        else if (!strcmp(field.c_str(), "QUOTEASK"))          {              bd->AddField((char *)QUOTEASK, 15);              bdmap["QUOTEASK"] = (void *)(&(item.QuoteAsk));          }        else if (!strcmp(field.c_str(), "QUOTEMID"))          {              bd->AddField((char *)QUOTEMID, 15);              bdmap["QUOTEMID"] = (void *)(&(item.QuoteMid));          }        else if (!strcmp(field.c_str(), "VALIDQUOTEBID"))          {              bd->AddField((char *)VALIDQUOTEBID, 15);              bdmap["VALIDQUOTEBID"] = (void *)(&(item.ValidQuoteBid));          }        else if (!strcmp(field.c_str(), "VALIDQUOTEASK"))          {              bd->AddField((char *)VALIDQUOTEASK, 15);              bdmap["VALIDQUOTEASK"] = (void *)(&(item.ValidQuoteAsk));          }        else if (!strcmp(field.c_str(), "VALIDQUOTEMID"))          {              bd->AddField((char *)VALIDQUOTEMID, 15);              bdmap["VALIDQUOTEMID"] = (void *)(&(item.ValidQuoteMid));          }        else if (!strcmp(field.c_str(), "BIDVOLUME"))          {              bd->AddField((char *)BIDVOLUME, 19);              bdmap["BIDVOLUME"] = (void *)(&(item.BidVolume));          }        else if (!strcmp(field.c_str(), "ASKVOLUME"))          {              bd->AddField((char *)ASKVOLUME, 19);              bdmap["ASKVOLUME"] = (void *)(&(item.AskVolume));                      }        else if (!strcmp(field.c_str(), "TRADEMARK"))          {              bd->AddField((char *)TRADEMARK, 2);              bdmap["TRADEMARK"] = (void *)(&(item.TradeMark));          }        else if (!strcmp(field.c_str(), "RUNSTATE"))          {              bd->AddField((char *)RUNSTATE, 2);              bdmap["RUNSTATE"] = (void *)(&(item.RunState));                      }        else if (!strcmp(field.c_str(), "VALUEDATE"))          {              bd->AddField((char *)VALUEDATE, 9);              bdmap["VALUEDATE"] = (void *)(&(item.ValueDate));                      }        else if (!strcmp(field.c_str(), "QUOTEBASIS"))          {              bd->AddField((char *)QUOTEBASIS, 15);              bdmap["QUOTEBASIS"] = (void *)(&(item.QuoteBasis));                      }        else if (!strcmp(field.c_str(), "QUOTEHIGH"))          {              bd->AddField((char *)QUOTEHIGH, 15);              bdmap["QUOTEHIGH"] = (void *)(&(item.QuoteHigh));                      }        else if (!strcmp(field.c_str(), "QUOTELOW"))          {              bd->AddField((char *)QUOTELOW, 15);              bdmap["QUOTELOW"] = (void *)(&(item.QuoteLow));                      }        else if (!strcmp(field.c_str(), "QUOTEOPEN"))          {              bd->AddField((char *)QUOTEOPEN, 15);              bdmap["QUOTEOPEN"] = (void *)(&(item.QuoteOpen));                      }        else if (!strcmp(field.c_str(), "QUOTECLOSE"))          {              bd->AddField((char *)QUOTECLOSE, 15);              bdmap["QUOTECLOSE"] = (void *)(&(item.QuoteClose));                      }        else if (!strcmp(field.c_str(), "REFRESHCOUNT"))          {              bd->AddField((char *)REFRESHCOUNT, 9);              bdmap["REFRESHCOUNT"] = (void *)(&(item.UpdateCount));                      }        /*        else if (!strcmp(field.c_str(), "REFRESHTIME"))          {              bd->AddField((char *)REFRESHTIME, 19);              bdmap["REFRESHTIME"] = (void *)(&datetimestr);          } */        else if (!strcmp(field.c_str(), "TERMID"))        {              bd->AddField((char *)TERMID, 5);              bdmap["TERMID"] = (void *)(&(item.TermID));          }        else if (!strcmp(field.c_str(), "SPOTBID"))        {              bd->AddField((char *)SPOTBID, 15);              bdmap["SPOTBID"] = (void *)(&(item.SpotBid));          }        else if (!strcmp(field.c_str(), "SPOTASK"))        {              bd->AddField((char *)SPOTASK, 15);              bdmap["SPOTASK"] = (void *)(&(item.SpotAsk));          }        else if (!strcmp(field.c_str(), "SPOTMID"))        {              bd->AddField((char *)SPOTMID, 15);              bdmap["SPOTMID"] = (void *)(&(item.SpotMid));          }        else if (!strcmp(field.c_str(), "MATURITYDATE"))        {              bd->AddField((char *)MATURITYDATE, 9);              bdmap["MATURITYDATE"] = (void *)(&(item.MaturityDate));          }          else          {            std::cout << "Error Field!" << std::endl;            /*            lang::mstring mstr;            mstr << "Error Field!";            throw lang::Exception(mstr.str()); */        }        bdsql = bdsql.erase(pos1, 6);      } while (1);    sql = bdsql;      _rowcount = 0;} 


这是我设计的类及其构造函数。
我先说说问题。这是一个多线程的服务端程序。包括mainthread, workthread, dbreadthread, dbwritethread四个线程。程序运行在Aix上。在workthread里面我通过TBindFWD *bindfwd = new TBindFWD(sqlfwd);这种方式得到一个实例。然后通过线程间调度给dbwritethread,执行完数据库语句之后,delete在workthread里面new出来的空间。
现在问题是这样的,程序执行几分钟后,workthread挂起,再过几分钟,然后整个server进程自动关闭。
因为这个服务端程序是改造项目,先前的服务端程序没有出现这样的问题,所以,我猜测是修改的代码出了问题。
另外,通过监控内存使用情况,发现,改造后的服务端程序,大概在内存占用为50M的时候自动关闭,而Aix能够承受的内存消耗是170M。并且改造前的服务端程序内存消耗达到100M的时候依然运行。
一开始我还认为是因为new出来的空间被释放后,没有被系统及时回收造成的,现在有点困惑,不确认是不是这个原因

[解决办法]
说实话看你的代码有点长,有点晕
只能逐步排除,虽然有点笨但是很有效。

程序执行几分钟后,workthread挂起,再过几分钟,然后整个server进程自动关闭。
看代码,应该和你的类本身关系不大。你的类应该是根据bdsql,最后生成一串标准的sql语句,赋值给string sql.
workthread挂起,这个是程序主动挂起(代码挂起)还是未知原因挂起?还是进程正常执行完后退出了?

如有可能的话,每个进程写个假数据测试一下,单独测试。哪个进程的代码改写的多,哪个是重点。
最好从自己的开始。

//=====================================================================================
看后面的过程应该类似于是这样的。
TBindFWD *bindfwd = new TBindFWD(sqlfwd);
dbwritethread *dbwrite = new dbwritethread;
dbwrite->Write(bindfwd->GetSQL())
//...
delete bindfwd;
delete dbwrite;

瞎给的意见
1,不清楚你们这个程序频繁度怎么样,如果很频繁这么重复的new 和 delete不太好,会造成内存碎片。
2,bdsql和sql,过于频繁如有可能参照1用个固定大小的char数组代替一下(预估一下足够大就行),先测试一下是不是这两个原因。
[解决办法]
重点检查你修改的代码看看吧,最好是输出日志看看

热点排行