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

ccpud 2011-10-30 08:52:52

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出来的空间被释放后,没有被系统及时回收造成的,现在有点困惑,不确认是不是这个原因
...全文
311 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccpud 2011-11-09
  • 打赏
  • 举报
回复
谢谢大家,最后问题自己解决了。原因有两个,一个是代码里面有一个地方new了之后忘记delete了(虽然new和delete的地方比较多,但还是说明自己有点粗心了);第二个是由于AIX内存空间的限制,针对这个,最后用的方法是ulimit -d unlimited。
hemiya 2011-10-31
  • 打赏
  • 举报
回复
10对/s,看情况而定。按理说频繁度真不算高,并且频繁度这个东西没什么标准,看实际情况。
我一般的情况下如果在几秒内一定会重复执行的东西,一般不会重复的new和delete,主要是看实际应用情况而定,没啥标准。
ccpud 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hemiya 的回复:]
我先试一试你说的。程序的功能差不多就如你所想的那样,是为了生成标准的sql语句,以减少数据库执行的时间。new和delete的频率差不多10对/s。
zzbinfo 2011-10-31
  • 打赏
  • 举报
回复
重点检查你修改的代码看看吧,最好是输出日志看看
hemiya 2011-10-30
  • 打赏
  • 举报
回复
说实话看你的代码有点长,有点晕
只能逐步排除,虽然有点笨但是很有效。

程序执行几分钟后,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数组代替一下(预估一下足够大就行),先测试一下是不是这两个原因。
阿霖 2011-10-30
  • 打赏
  • 举报
回复
还有就是 CreateThread出来的线程句柄是要通过CloseHandle来关闭的~
阿霖 2011-10-30
  • 打赏
  • 举报
回复
是不是没有设置线程之间的互斥呢 我之前遇到过这种情况
whoami1978 2011-10-30
  • 打赏
  • 举报
回复
帮顶,学习

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧