peakzhang 发表于 2007-12-31 22:23:44

关于任务线程创建后退出不完全的问题

服务端和客户端的源程序在附件中,主要是想实现了FTP服务器的功能,服务端用了ACE_TP_Reactor实现,关于工作流程和服务端的主要类的描述在附件中有说明。现在的问题是
服务端在接爱一个连接完成数据传输后有些线程没有退出,再次接爱连接时有时会出错。

peakzhang 发表于 2007-12-31 22:23:52

win平台,VC6。客户端下载文件没有问题。不需考虑,客户端程序中写死了要下载d:\a.rar到d:\temp\a.rar

主要是服务端的程序在使用多线程后出现的同步处理上的错误,使线程退出不全,或是出现了宏框报错。

服务端的程序在应用的流程上不会有问题,所以除了在附件的说明中说明的几个主要的类外一些和应用有关的类方法的处理是正确(也不用考虑)。

peakzhang 发表于 2007-12-31 22:24:21

线程同步有典型的错误

void CClientService::SetWorkFinish()
{
m_CmdWork.msg_queue()->deactivate();
m_CmdWork.m_Exit = 0;    //必须加保护,如InterlockedExchange操作等等
m_CmdWork.flush();
m_CmdWork.wait();
}
int CmdWork::svc(void)
{
while(done())
{
   ACE_Message_Block *mb = 0;
   if(this->getq(mb) == -1)
   {
    CClientService* ConPtr = ACE_static_cast(CClientService*, m_ConServerThis_);
    if(ConPtr->m_ConFlag == 0 || ConPtr->m_ConFlag == 10){
   //退出数据服务端的事件循环
   this->SetDone();
    }
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("%ITime[%D]>>>>>>>>>>>this[%d]msg_queue[%d].\n"),this, this->msg_queue()));   
    return 0;
   }
   //处理消息
   Proccess_Task(mb);
}
return 0;
}
int CmdWork::done()
{
return m_Exit; //错误!没有线程同步保护
}

我还没有运行你的代码,只是从上面来看,就存在这个问题。这个问题将导致不确定的线程错误 - 线程可能不能正确退出,导致程序问题。你修改一下,应该可以解决了。

peakzhang 发表于 2007-12-31 22:24:36

加锁后解决,但有些还是没想明白,一个连接一个任务线程,虽然都用的是同一个SVC但其控制变量m_exit是在每个连接中都有一个实例,也是就是说每个实列都会有自己的m_exit变量的值,但为什么还要加锁后才能正常工作呢。

peakzhang 发表于 2007-12-31 22:24:44

void CClientService::SetWorkFinish()
int CmdWork::done()
{
return m_Exit; //错误!没有线程同步保护
}
他们在不同的线程中运行,当然需要加锁保护了。不然必定出错。

peakzhang 发表于 2007-12-31 22:24:57

线程操作时候的常识。多线程存取一个变量,必须加保护,否则一定出错,而且有随机的特性。
页: [1]
查看完整版本: 关于任务线程创建后退出不完全的问题