创建了一个动态连接库,在初始化的时候创建了两个线程,这两个线程原本是要接受用户发来的消息(使用PostThreadMessage函数)并进行处理的,问题出现了:1:当我向线程发消息的时候,如果此时很快的主线程结束了,那么,动态连接库中的线程根本得不到运行,系统马上转入动态链接库清理例程中运行,并且,似乎这个时候虽然那两个服务线程尚未结束(我采用的方法是向线程发送WM_QUIT消息通知他们结束自己),但是系统并不再为他们分配处理起了,问题是,我此时已经向他们发送了两个消息了,该怎么办才能让他们有充分得时间运行来处理消息呢?2:也是上面的那个动态连接库,在结束的时候,我的代码向线程发送WM_QUIT通知线程结束自己,然后使用WaitForSingleObject分别进行等待,超时则强制结束,可是,问题是,我在线程中加入了断点,试图跟踪对WM_QUIT的处理,可系统并没有进入线程内部就直接运行下面的代码了,也就是说,虽然消息被发送出去了,但是我的线程并没有对其进行处理,也就是说他们没有正常结束,可是GetExitCode却显示他们正常结束了,这又是怎么回事?而且WaitForSingleObject立即返回,并没有给时间让线程结束。3:还有在创建线程的时候,中断运行显示,在执行完_beginthreadex之后,系统仍然只有一个线程在运行,那么新创建的线程去哪里了?这个库没有使用MFC,哪位高人指点?

解决方案 »

  1.   

    第一个问题:你可在向线程发送消息后,WaitForSingleObject(hThread, INFINIT)来等待线程执行结束
    第二个问题: 你的线程是否建立了消息循环?记得线程中要建立消息循环,需要先PeekMessage再GetMessage
    第二个问题: 不要使用_beginthreadex,而使用系统API  CreateThread
      

  2.   

    1: 用发送WM_QUIT的办法结束线程有问题,这个消息是用来结束应用程序的,不应该用PostMessage来发送这个消息。参见:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowmessages/wm_quit.asp当调用PostThreadMessage时,如果线程还没有消息队列,调用会失败。这时应当Sleep一段时间再重复调用PostThreadMessage,直到成功。2: 结束线程可以用Event,也可以用自定义消息的,在线程函数中使用WaitForSingleObject/WaitForMultipleObject/MsgWaitForMultipleObject来处理这个事件/消息。不能使用WM_QUIT来结束线程。3: 不明白
      

  3.   

    1、可以让你的主线程适当的Sleep一下,或者采用WaitForSingleObject(hThread,...)的方法来等待你的辅助县城结束,再继续执行主线程2、用PostMessage是向目标线程的消息队列中发送消息,如果你的线程是一个没有消息循环的线程,你的消息是传递不到目的地的!3、中断运行显示
    能说的清楚一点吗?
      

  4.   

    1、我确实是使用的WaitForSingleObgjct函数等待了,也尝试过Sleep,不过,当这两个调用处于DllMain中的时候,他们完全失去了效力,目前我的解决方法是单独用一个函数来结束他们,我发现当不是由DllMain中执行这两个函数的时候,他们完全按照预想的运行了,是不是与DllMain序列化有关呢?2、我的线程虽然是工作者线程,但是他们是消息驱动的,也就是说,内部使用了GetMessage和PeekMessage接受调用线程发送的消息,同时,由于WM_QUIT消息的特殊性,我把它作为通知线程结束的消息,因为简单的发送这个消息给一个线程并不会导致应用程序的结束。3、问题是这样的,当我把线程创建工作放在DllMain中的时候,每初始化一个线程我就中断一次,然后察看VC的那个“线程”对话框,结果发现,虽然我调用了_beginthreadex但是系统并没有多出线程来,直到DllMain结束,这是为什么呢?似乎在DllMain执行的时候系统中就只有一个线程,不管是初始化还是销毁:(4、关于_beginthreadex,使用它是因为我的线程使用了一些C运行库的内容,如果直接使用CreateThread,则会导致全局数据冲突,所以只能使用者个函数来创建线程,详情请看《Windows多线程程序设计》:)
      

  5.   

    DllMain执行的时候系统中就只有一个线程,it's true
      

  6.   

    就是说不管怎样,都不可能在DllMain中结束其他的线程,我是说通知结束,只能强制结束是么?
      

  7.   

    当然可在dllmain()通知结束或是强制结束某一子线程.只不过这个dllmain()可不是那个main()或是winmain(),后者只会被调用一次,其入口是程序开始,其出口是程序结束.而dllmain()是可能被调用无数次的,你在dllmain()中呼叫线程时,你是否很清楚那个dllmain()是第几次以及为什么被调用?