» 您尚未 登录   注册 | 社区服务 | FTP中心 | 帮助 | 社区 | 无图版 | 测试百科  | 测试Blog 
软件测试基地论坛 -> 测试开发技术 -> 『转贴』大家好 看看这个东东 很有意思哦
 XML   RSS 2.0   WAP 

--> 本页主题: 『转贴』大家好 看看这个东东 很有意思哦 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题
google




该用户目前不在线
级别: 测试新手
精华: 0
发帖: 1
基地声望: 2 点
基地币: 6425 Bug
基地贡献: 0 点
好评度: 0 点
在线时间:0(小时)
注册时间:2006-06-30
最后登录:2006-06-30
查看作者资料 发送短消息 推荐此帖 引用回复这个帖子

『转贴』大家好 看看这个东东 很有意思哦


图片:


图片:

转自:http://blog.csdn.net/johnlya
   
大家好 CSDN上的有一个好东东 呵呵 挺有意思 大家可以看看哦


    本文主要测试的是eXtremeDB的事务和BerkeleyDB的自动加锁的在多线程调度下的成功率以及所花费的时间的差别。(操作数为10万次)
1、eXtremeDB的测试源程序:
#include "McoDBInfo.h"
#include "include\mco.h"
#include "platform\platform.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DBSIZE (1024*1024*100)
#define PAGESIZE 64
#define NOBJECTS 5
#define NTHREADS 6
#define NEXECUTE 100000
const int MAP_ADDRESS = 0x20000000;
const char dbN[] = "McoDBInfo";
mco_db_h db =0;
void* start_mem;
HANDLE hThread = 0,hDeleThread = 0,hUpdateThread[NTHREADS] = {NULL},hCheckThread = 0;
volatile BOOL threadsign = FALSE,UpdateSign = FALSE,DeleteSign = FALSE,CheckSign = FALSE;
unsigned long m_iRecord[3] ={0},m_couter =0,m_iSuccess[3] = {0};
DWORD m_start = 0,m_end = 0;
CRITICAL_SECTION m_Critical;
LARGE_INTEGER frequent;
LARGE_INTEGER startcount,endcount;
void insertData(mco_db_h db)
{
MCO_RET rc;
TimeStamp timec;
mco_trans_h t;
double m_value = 0.0;
rc = mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t);
m_couter ++;
EnterCriticalSection(&m_Critical);
m_iRecord[0]++;
LeaveCriticalSection(&m_Critical);

TimeStamp_new(t,&timec);
m_value = 1.0*m_couter;
TimeStamp_m_iID_put(&timec,m_value);
rc = mco_trans_commit(t);
if(rc == MCO_S_OK)
{
// printf("%d\n",m_iRecord);fflush( stdout );
EnterCriticalSection(&m_Critical);
m_iSuccess[0]++;
LeaveCriticalSection(&m_Critical);
}
else
{
printf("Insert Error!!!\n");
}
}
void DeletData(mco_db_h db)
{
MCO_RET rc;
TimeStamp timec;
mco_trans_h t;
mco_cursor_t timecsr;
mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t);
EnterCriticalSection(&m_Critical);
m_iRecord[1]++;
LeaveCriticalSection(&m_Critical);

TimeStamp_list_cursor(t,&timecsr);
rc =mco_cursor_first(t,&timecsr);
rc =TimeStamp_from_cursor(t,&timecsr,&timec);
rc = TimeStamp_delete(&timec);
rc = mco_trans_commit(t);
if(rc == MCO_S_OK)
{
// printf("%d\n",m_iRecord);fflush( stdout );
EnterCriticalSection(&m_Critical);
m_iSuccess[1]++;
LeaveCriticalSection(&m_Critical);
}
else
{
printf("delete Error!!!\n");
}
}
void UpdateData(mco_db_h db)
{
MCO_RET rc;
TimeStamp timec;
mco_trans_h t;
mco_cursor_t timecsr;
mco_trans_start(db,MCO_READ_WRITE,MCO_TRANS_FOREGROUND,&t);
EnterCriticalSection(&m_Critical);
m_iRecord[2]++;
LeaveCriticalSection(&m_Critical);

TimeStamp_list_cursor(t,&timecsr);
rc =mco_cursor_last(t,&timecsr);
rc =TimeStamp_from_cursor(t,&timecsr,&timec);
TimeStamp_m_iID_put(&timec,m_couter);
rc = mco_trans_commit(t);
if(rc == MCO_S_OK)
{
// printf("%d\n",m_iRecord);fflush( stdout );
EnterCriticalSection(&m_Critical);
m_iSuccess[2]++;
LeaveCriticalSection(&m_Critical);
}
else
{
printf("Update Error!!!\n");
}
}
DWORD WINAPI InsertThread( LPVOID lpParam )
{
while(!threadsign)
{
// HANDLE m_hMutex;
// 创建互斥量
// m_hMutex = CreateMutex(NULL, FALSE, "DELETDB");
// 检查错误代码
// if (GetLastError() == ERROR_ALREADY_EXISTS)
// {
// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// continue;
// }
insertData(db);

// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// Sleep(25);

}

return 0;
}
//删除数据
DWORD WINAPI DeleteThread( LPVOID lpParam )
{
while(!DeleteSign)
{
// HANDLE m_hMutex;
// 创建互斥量
// m_hMutex = CreateMutex(NULL, FALSE, "DELETDB");
// 检查错误代码
// if (GetLastError() == ERROR_ALREADY_EXISTS)
// {
// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// continue;
// }
DeletData(db);

// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// Sleep(25);
}

return 0;
}
//更新数据
DWORD WINAPI UpdateThread( LPVOID lpParam )
{
while(!UpdateSign)
{
// HANDLE m_hMutex;
// 创建互斥量
// m_hMutex = CreateMutex(NULL, FALSE, "DELETDB");
// 检查错误代码
// if (GetLastError() == ERROR_ALREADY_EXISTS)
// {
// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// continue;
// }
UpdateData(db);

// CloseHandle(m_hMutex);
// m_hMutex = NULL;
// Sleep(25);
}

return 0;
}
//监测数据
DWORD WINAPI CheckThread( LPVOID lpParam )
{
mco_runtime_info_t *m_info = (mco_runtime_info_t *)lpParam;
while(!CheckSign)
{
if ((m_iRecord[0]+m_iRecord[1]+m_iRecord[2])>NEXECUTE)
{
  threadsign = TRUE;
  UpdateSign = TRUE;
  DeleteSign = TRUE;
  unsigned long elaspe;
  QueryPerformanceCounter(&endcount);
  elaspe = ((double)(endcount.QuadPart - startcount.QuadPart)
  /(double)frequent.QuadPart*1000*1000);
  Sleep(10);   //等待事务做完后关闭线程
  printf("Total InsertTrans is %ld\n",m_iRecord[0]);
  printf("Successful InsertTrans is %ld\n",m_iSuccess[0]);
  printf("Total DeletTrans is %ld\n",m_iRecord[1]);
  printf("Successful DeletTrans is %ld\n",m_iSuccess[1]);
  printf("Total UpdateTrans is %ld\n",m_iRecord[2]);
  printf("Successful UpdateTrans is %ld\n",m_iSuccess[2]);
  printf("Total Trans is %ld\n",m_iRecord[0]+m_iRecord[1]+m_iRecord[2]);
  printf("Successful Trans is %ld\n",m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2]);
  int lostrate = 0;
  lostrate = (double)(m_iRecord[0]+m_iRecord[1]+m_iRecord[2]
  -(m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2]))
  /(double)(m_iRecord[0]+m_iRecord[1]+m_iRecord[2])*100;
  printf("Lost data rate is (%):%d\n",lostrate);
  printf("Total Time is %ld millisecond\n",elaspe/1000);
  printf("Time every Trans is %ld microsecond\n",elaspe/(m_iRecord[0]+m_iRecord[1]+m_iRecord[2]));
  printf("Time every Success is %ld micorosecond\n",elaspe/(m_iSuccess[0]+m_iSuccess[1]+m_iSuccess[2]));
 
  if (hThread)
  CloseHandle(hThread);
  for (int i=0;i<NTHREADS;i++)
  {
  if (hUpdateThread)
  CloseHandle(hUpdateThread);
  }
  if (hDeleThread)
  CloseHandle(hDeleThread);
  DeleteCriticalSection(&m_Critical);
  mco_db_disconnect(db);
  mco_db_close(dbN);
  mco_runtime_stop();
  if(!m_info->mco_shm_supported)
  free(start_mem);
  CheckSign = TRUE;
}
}
ExitThread(10);
return 0;
}int file_reader(void *stream_handle /* FILE * */, /* OUT */ void * to, unsigned max_nbytes)
{
FILE *f = (FILE*)stream_handle;
int nbs = fread(to,1,max_nbytes,f);
return nbs;
}
int main(int argc, char* argv[])
{
MCO_RET rc;
DWORD dwThreadID,dwThreadID2,dwThreadID3,dwThreadID4;
unsigned long eslapetime=0;
mco_runtime_info_t info;
if (!QueryPerformanceFrequency(&frequent))
{
printf("not supported!\n");
}

mco_get_runtime_info( &info);
if ( info.mco_shm_supported ) {
start_mem = (char*)MAP_ADDRESS;
}
else {
start_mem = (char*)malloc(DBSIZE);
if (!start_mem) {
  printf("Couldn't allocated memory\n");
  exit (1);
}
};
/* start db engine */
if ( mco_runtime_start() != MCO_S_OK) {
printf( "\nUnable to start database engine\n" );
if ( !info.mco_shm_supported )
  free( start_mem );
exit(-1);
};
mco_db_kill(dbN);
rc = mco_db_open(dbN, McoDBInfo_get_dictionary(),start_mem,DBSIZE,(uint2)PAGESIZE);

if(rc){
printf("\ncreate db err, %d\n", rc);
if(!info.mco_shm_supported)
  free(start_mem);
exit(1);
}
rc = mco_db_connect(dbN, &db);
if(rc){
printf("database connect err\n");
exit(-1);
}
//
InitializeCriticalSection(&m_Critical);
QueryPerformanceCounter(&startcount);
hCheckThread = CreateThread( NULL, 0, CheckThread, (LPVOID)&info, 0, &dwThreadID4 );
hThread = CreateThread( NULL, 0, InsertThread, (LPVOID)NULL, 0, &dwThreadID );
for (int i=0;i<NTHREADS;i++)
{
hUpdateThread = CreateThread( NULL, 0, UpdateThread, (LPVOID)NULL, 0, &dwThreadID2 );
}
hDeleThread = CreateThread( NULL, 0, DeleteThread, (LPVOID)NULL, 0, &dwThreadID3 );


WaitForSingleObject(hCheckThread,INFINITE);
if (hCheckThread)
CloseHandle(hCheckThread);
return 0;
}
其数据库为:
#define int1     signed<1>
#define int2     signed<2>
#define int4     signed<4>
#define int8     signed<8>
#define uint8   unsigned<8>
#define uint4   unsigned<4>
#define uint2   unsigned<2>
#define uint1   unsigned<1>


declare database McoDBInfo;
class TimeStamp
{
double m_iID;   //时间戳ID
list; //
};
2、BerkeleyDB的测试源程序为:

// DbPerformance.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <sys/types.h>
#include "afxwin.h"
#include <iostream>
#include <iomanip>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "db_cxx.h"
using namespace std;
#define LOOP 100000
#define THREAD_COUNT 8
#define NTHREADS 6
#define NEXECUTE 100000
HANDLE hThread = 0,hDeleThread = 0,hUpdateThread[NTHREADS] = {NULL},hCheckThread = 0;
volatile BOOL threadsign = FALSE,UpdateSign = FALSE,DeleteSign = FALSE,CheckSign = FALSE;
const u_int32_t pagesize =1024;
const u_int   bulkbufsize = 4 * 1024 * 1024;
const u_int     logbufsize = 8 * 1024 * 1024;
const u_int     cachesize = 100 * 1024 * 1024;
const u_int   datasize = 32;
const u_int keysize = 8;

class CDbController{
public:
CDbController(char* dbName);
~CDbController();
int WriteMessage();
int UpdateMessage();
int DeleteMessage();
int writeMessage(int number);
int readMessage(int number);
int printAllRc();
void StartThread();
void WaitForThread();
private:
Db * myDb;
DbEnv * myEnv;

unsigned long m_iRecord[3];
unsigned long m_iSuccess[3];
LARGE_INTEGER frequent;
LARGE_INTEGER startcount,endcount;
CRITICAL_SECTION m_Critical;

static DWORD WINAPI InsertThread(LPVOID lpParam);
static DWORD WINAPI DeleteThread(LPVOID lpParam);
static DWORD WINAPI UpdateThread(LPVOID lpParam);
static DWORD WINAPI CheckThread( LPVOID lpParam );

}
;
DWORD WINAPI CDbController::InsertThread( LPVOID lpParam )
{
CDbController *pControl = (CDbController*)lpParam;
while(!threadsign)
{
pControl->WriteMessage();
}

return 0;
}
//删除数据
DWORD WINAPI CDbController::DeleteThread( LPVOID lpParam )
{
CDbController *pControl = (CDbController*)lpParam;
while(!DeleteSign)
{
pControl->DeleteMessage();
}

return 0;
}
//更新数据
DWORD WINAPI CDbController::UpdateThread( LPVOID lpParam )
{
CDbController *pControl = (CDbController*)lpParam;
while(!UpdateSign)
{
pControl->UpdateMessage();
}

return 0;
}
//监测数据
DWORD WINAPI CDbController::CheckThread( LPVOID lpParam )
{
CDbController *pControl = (CDbController*)lpParam;
while(!CheckSign)
{
if ((pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2])>NEXECUTE)
{
  threadsign = TRUE;
  UpdateSign = TRUE;
  DeleteSign = TRUE;
  unsigned long elaspe;
  QueryPerformanceCounter(&pControl->endcount);
  elaspe = ((double)(pControl->endcount.QuadPart - pControl->startcount.QuadPart)
  /(double)pControl->frequent.QuadPart*1000*1000);
  Sleep(10);   //等待事务做完后关闭线程
  printf("Total InsertTrans is %ld\n",pControl->m_iRecord[0]);
  printf("Successful InsertTrans is %ld\n",pControl->m_iSuccess[0]);
  printf("Total DeletTrans is %ld\n",pControl->m_iRecord[1]);
  printf("Successful DeletTrans is %ld\n",pControl->m_iSuccess[1]);
  printf("Total UpdateTrans is %ld\n",pControl->m_iRecord[2]);
  printf("Successful UpdateTrans is %ld\n",pControl->m_iSuccess[2]);
  printf("Total Trans is %ld\n",pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2]);
  printf("Successful Trans is %ld\n",pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2]);
  int lostrate = 0;
  lostrate = (double)(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2]
  -(pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2]))
  /(double)(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2])*100;
  printf("Lost data rate is (%):%d\n",lostrate);
  printf("Total Time is %ld millisecond\n",elaspe/1000);
  printf("Time every Trans is %ld microsecond\n",elaspe/(pControl->m_iRecord[0]+pControl->m_iRecord[1]+pControl->m_iRecord[2]));
  printf("Time every Success is %ld micorosecond\n",elaspe/(pControl->m_iSuccess[0]+pControl->m_iSuccess[1]+pControl->m_iSuccess[2]));
  if (hThread)
  CloseHandle(hThread);
  for (int i=0;i<NTHREADS;i++)
  {
  if (hUpdateThread)
  CloseHandle(hUpdateThread);
  }
  if (hDeleThread)
  CloseHandle(hDeleThread);
  DeleteCriticalSection(&pControl->m_Critical);
  CheckSign = TRUE;
}
}
ExitThread(10);
return 0;
}
void CDbController::StartThread()
{
DWORD dwThreadID1,dwThreadID2,dwThreadID3,dwThreadID4;
InitializeCriticalSection(&m_Critical);
if (!QueryPerformanceFrequency(&frequent))
{
printf("not supported!\n");
}
QueryPerformanceCounter(&startcount);
hCheckThread = CreateThread( NULL, 0, CheckThread, (LPVOID)this, 0, &dwThreadID4 );
hThread = CreateThread( NULL, 0, InsertThread, (LPVOID)this, 0, &dwThreadID1 );
for (int i=0;i<NTHREADS;i++)
{
hUpdateThread = CreateThread( NULL, 0, UpdateThread, (LPVOID)this, 0, &dwThreadID2 );
}
hDeleThread = CreateThread( NULL, 0, DeleteThread, (LPVOID)this, 0, &dwThreadID3 );

}
int CDbController:: readMessage(int number){

char keychar[keysize];
char datachar[datasize];
Dbt key(keychar,keysize);
key.set_ulen(keysize);
key.set_flags(DB_DBT_USERMEM);
Dbt data(datachar,datasize);;
data.set_ulen(datasize);
data.set_flags(DB_DBT_USERMEM);

for(int i=0;i<number;i++){
sprintf(keychar,"%4d",i);
int ret=myDb->get(0,&key,&data,0);
}
return 0;
}
CDbController::printAllRc(){
Dbc *dbcp;
myDb->cursor(NULL, &dbcp, 0);

// Walk through the table, printing the key/data pairs.
Dbt key;
Dbt data;
while (dbcp->get(&key, &data, DB_NEXT) == 0) {
int *key_string = (int *)key.get_data();
int *data_string = (int *)data.get_data();
printf("%d:%d\n",*key_string,*data_string);
//cout << &key_string << " : " << &data_string << "\n";
}
dbcp->close();
return 0;
}
CDbController::CDbController(char* dbName){
u_int32_t env_flags=
DB_CREATE
|DB_INIT_MPOOL
|DB_INIT_LOCK
|DB_LOCKDOWN
|DB_THREAD
// |DB_SYSTEM_MEM;
|DB_PRIVATE;

u_int32_t db_flags=DB_CREATE;
std::string envHome("test");
for (int i=0;i<3;i++)
{
m_iRecord =0;
m_iSuccess =0;
}
myEnv=new DbEnv(0);
myEnv->set_cachesize(0,cachesize,0);
myEnv->set_flags(DB_LOG_INMEMORY, 1);
// Specify the size of the in-memory log buffer.
  myEnv->set_lg_bsize(100 * 1024 * 1024);

try{
myEnv->open(envHome.c_str(),env_flags,0666);
myDb=new Db(myEnv,0);
myDb->set_error_stream(&cerr);
myDb->set_errpfx("Performance");
myDb->set_pagesize(pagesize); /* Page size: 1K. */
// myDb->set_cachesize(0, cachesize, 0);
myDb->open(NULL,
  NULL,
  NULL,
  DB_BTREE,
  //DB_HASH,
  db_flags,
  0666);

}catch(DbException &e){
std::cerr<<"Error opening environment"<<std::endl;
std::cerr<<e.what()<<std::endl;
exit(-1);
}catch(std::exception &e){
std::cerr<<e.what()<<std::endl;
exit(-1);
}


}
void CDbController::WaitForThread()
{
WaitForSingleObject(hCheckThread,INFINITE);
}
CDbController::~CDbController(){
myDb->close(0);
myEnv->close(0);
}
int CDbController:: WriteMessage(){
char keychar[keysize], datachar[datasize];
memset(keychar,'1',keysize);
memset(datachar,'0',datasize);
EnterCriticalSection(&m_Critical);
m_iRecord[0]++;
LeaveCriticalSection(&m_Critical);
Dbt key(keychar,keysize);
Dbt data(datachar,datasize);
sprintf(keychar,"%4d",m_iRecord[0]);
int ret = myDb->put(0, &key, &data,0);
if (ret==0)
{
EnterCriticalSection(&m_Critical);
m_iSuccess[0]++;
LeaveCriticalSection(&m_Critical);
}
return 0;
}
int CDbController:: UpdateMessage(){
Dbc *dbcp;
myDb->cursor(NULL, &dbcp, 0);

char keychar[keysize], datachar[datasize];
memset(keychar,'1',keysize);
memset(datachar,'0',datasize);
EnterCriticalSection(&m_Critical);
m_iRecord[2]++;
LeaveCriticalSection(&m_Critical);
Dbt key(keychar,keysize);
Dbt data(datachar,datasize);
sprintf(keychar,"%4d",m_iRecord[2]);
int ret = dbcp->put(&key, &data,DB_KEYFIRST);
if (ret==0)
{
EnterCriticalSection(&m_Critical);
m_iSuccess[2]++;
LeaveCriticalSection(&m_Critical);
}
dbcp->close();
return 0;
}
int CDbController:: DeleteMessage(){
Dbc *dbcp;
int ret = 0;
myDb->cursor(NULL, &dbcp, 0);
m_iRecord[1]++;
char keychar[keysize], datachar[datasize];
memset(keychar,'1',keysize);
memset(datachar,'0',datasize);
EnterCriticalSection(&m_Critical);
m_iRecord[2]++;
LeaveCriticalSection(&m_Critical);

Dbt key(keychar,keysize);
Dbt data(datachar,datasize);
sprintf(keychar,"%4d",m_iRecord[1]);

ret = dbcp->get(&key, &data,DB_SET);
ret= dbcp->del(0);
if (ret==0)
{
EnterCriticalSection(&m_Critical);
m_iSuccess[1]++;
LeaveCriticalSection(&m_Critical);
}
dbcp->close();
return 0;
}
int CDbController:: writeMessage(int number){
for (int i=0;i<number;i++)
{
char keychar[keysize], datachar[datasize];
memset(keychar,'1',keysize);
memset(datachar,'0',datasize);

Dbt key(keychar,keysize);
Dbt data(datachar,datasize);
sprintf(keychar,"%4d",i);
int ret = myDb->put(0, &key, &data,0);
}
return 0;
}
int main(int argc, char* argv[])
{
LARGE_INTEGER frequent;
LARGE_INTEGER startcount,endcount;
unsigned long elapsetime =0;
// Sleep(2000);
if (!QueryPerformanceFrequency(&frequent))
{
printf("not supported!\n");
}
CDbController controller("abcd");
printf("\n start test performance.\n");
printf("key size= %d byte , data size = %d byte, record number= %d\n",keysize,datasize,LOOP);
printf("lock initialized.\n");

//计时开始
QueryPerformanceCounter(&startcount);
controller.writeMessage(LOOP);
QueryPerformanceCounter(&endcount);
elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000;
//打印单线程写耗时
printf("single thread writing, time cost (mm):%ld\n",elapsetime);

//计时开始
QueryPerformanceCounter(&startcount);
controller.writeMessage(LOOP);
QueryPerformanceCounter(&endcount);
elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000;
//打印单线程更新耗时
printf("single thread writing, time cost (mm):%ld\n",elapsetime);
//计时开始
QueryPerformanceCounter(&startcount);
controller.readMessage(LOOP);
QueryPerformanceCounter(&endcount);
elapsetime = (double)(endcount.QuadPart - startcount.QuadPart)/(double)frequent.QuadPart*1000*1000;
//打印单线程更新耗时
printf("single thread reading, time cost (mm):%ld\n",elapsetime);
//多线程调度
CDbController controllere("abcde");
controllere.StartThread();
printf("start multiple thread writing and reading.\n");
controllere.WaitForThread();
return 0;
}
3、测试结果如下:如图
eXtremeDB:

BerkeleyDB:

[楼 主] | Posted: 2006-06-30 16:23 顶端
土土松


该用户目前不在线
级别: 论坛版主
精华: 7
发帖: 1689
基地声望: 246 点
基地币: 2765 Bug
基地贡献: 6 点
好评度: 48 点
在线时间:1031(小时)
注册时间:2005-10-30
最后登录:2007-10-29
查看作者资料 发送短消息 推荐此帖 引用回复这个帖子



貌似出了一把汗 。。。。  

MSN:ss2maomao@hotmail.com
我的博客已经升级:
http://hi.baidu.com/lidanny
欢迎莅临~~!!~~

[1 楼] | Posted: 2006-07-04 14:32 顶端

软件测试基地论坛 -> 测试开发技术




软件测试基地上海测仕信息技术有限公司旗下网站
Copyright © 2005-2007 Cntesting.com, All Rights Reserved
沪ICP备06057721号

Powered by PHPWind Code © 2003-06 PHPWind
Total 0.187207(s) query 5, Time now is:10-13 11:38, Gzip disabled
You can contact us


每日一句:Loading...