//问题一://有这样两个线程:HANDLE m_event = NULL:void threadPro1(...)
{
...
SetEvent(m_event);
...
}void threadPro2(...)
{
...
WaitForSingleObject(m_event,INFINITE);
ResetEvent((m_event);
...
}
//如果开始时是threadPro2线程处于运行状态,那么CPU对threadPro1和threadPro2是怎么调度的?
我的问题是:线程threadPro2->Wait Event,然后到线程threadPro1运行,当线程1给事件设置信号后线程又是怎么运行的?问题二:
    当在一个线程内创建一个新的线程时,如果创建的新线程是创建后立即执行和创建后挂起,然后紧接着就ResumeThread该线程,那么这两种方式的区别(操作系统在线程调度上的区别)。

解决方案 »

  1.   

    我的问题是:线程threadPro2->Wait Event,然后到线程threadPro1运行,当线程1给事件设置信号后线程又是怎么运行的? 
    ============================================================================
    线程threadPro2和线程threadPro1同时运行。
      

  2.   

    其实waitforsingleobject就是一个不断检测信号状态的功能块,类似为while(...){},如果检测到信号就往下执行。所以也就是如果threadPro2获得CPU时间,他就不断这样运行,剩下的就是普通的线程调度了。第二个问题我觉得其实就是新创建的线程何时放入线程池中排队等待CPU时间片的问题,应该只是一个排队前后的问题。
      

  3.   

    WaitForSingleObject函数中的Handle是内核对象句柄。
    你的m_event初始化了吗?
    m_event = CreateEvent(....)CPU对threadPro1和threadPro2是怎么调度的问题。
    要看threadPro1和threadPro2的创建时机和它们的线程优先级等级。你上边的运行流程是这样的:
    threadPro2(...) 运行到WaitForSingleObject(m_event,INFINITE)时,该线程就暂停了,一直等到threadPro1(...)中执行了SetEvent(m_event)为止。问题二:
    这两中在调度上边是没有区别的。
    它们的主要区别是:
    创建时挂起线程后,你可以改变线程内核对象结构体(CONTEXT),该结构体保存了线程运行时信息。
    比喻你可以改变线程优先级、线程堆栈值等等(SetThreadContext(.....)。
      

  4.   


    在单CPU的机器上,不可能做到真正的同时运行。多任务的系统最基本的原理就是把CPU分成很多时间片,然后以某一个可以执行的基本单位为对象(如线程)来调度运行。所以你这个理解是正确的。
      

  5.   


    当然了,这两个线程的优先级是相同的,并且你的m_event是初始化了的。
      

  6.   

    线程的运行顺序是不固定的,应该是有受OS或CPU控制的,所以我同意楼上的说法
      

  7.   

    从微观上来说:
    //问题一:我的问题是:线程threadPro2->Wait Event,然后到线程threadPro1运行,当线程1给事件设置信号后线程又是怎么运行的? -->当线程threadPro2->WaitFor...执行时,系统将threadPro2放入等待队列并将线程切换到threadPro1(假设系统中没有其它满足运行条件并等待运行的线程), 当线程1设置信号量时,系统调整了线程2的优先级(它已经满足了运行条件,等CPU有空闲时就能运行),如果此时线程1的时间片用完了,那么系统将线程1放入等待队列,切换并执行线程2后续代码;如果此时线程1时间片还没有用完,那么线程1将继续执行。
    问题二: 
        当在一个线程内创建一个新的线程时,如果创建的新线程是创建后立即执行和创建后挂起,然后紧接着就ResumeThread该线程,那么这两种方式的区别(操作系统在线程调度上的区别)。--> 回答同问题1, 不管创建的新线程是否设置成立即执行,系统都会将它放入等待队列(因为目前是在当前线程的执行时间片内),由于每个CPU都有一个等待执行线程的队列,所以如果是多核系统,创建的是个立即执行的线程,并且某个cpu正好有空,那么新建线程将运行于那个空闲cpu上,和当前线程物理上同时执行。如果是单核系统,那么情况就有趣得多,即使当前线程创建了一个挂起的线程,如果在它cpu时间片用完前执行了ResumeThread,那么效果和直接创建一个立即运行的线程是完全一样的。
      

  8.   


    1,请注意,这里的“同时”加了引号。就是说,你可以认为它是同时运行的,这部分是操作系统为我作做的,对一般的应用来讲,我们不一定要知道CPU是多核还是单核,我们用多线程就当他是同时的就是了。2,可以认为没有差别。
      

  9.   

    谢谢各位!尤其谢谢Idle_,您对该问题本意的理解程序和对问题的解答同样的深该。谢谢!
      

  10.   


    谢谢各位! 尤其谢谢Idle_,您对该问题本意的理解程度和对问题的解答同样的深刻。谢谢!
      

  11.   

    在单CPU的机器上,不可能做到真正的同时运行。多任务的系统最基本的原理就是把CPU分成很多时间片,然后以某一个可以执行的基本单位为对象(如线程)来调度运行。 
      

  12.   

    WaitForSingleObject()函数是用来切换线程使用CPU状态的:
    如果等待的事件发生,内核将此线程放到就绪队列;
    如果等待的事件没有发生,内核将此线程放到阻塞对列;WaitForSingleObject()不同与轮询.轮询是尽可能的占用CPU时间的.
      

  13.   

    CPU对threadPro1和threadPro2是怎么调度的问题。
    要看threadPro1和threadPro2的创建时机和它们的线程优先级等级。
    threadPro2(...) 运行到WaitForSingleObject(m_event,INFINITE)时,该线程就暂停了,threadPro2(...)进入等待状态,一直等到threadPro1(...)中执行了SetEvent(m_event)为止。问题二:
    这两中在调度上边是没有区别的。
    它们的主要区别是:
    创建时挂起线程后,你可以改变线程内核对象结构体(CONTEXT),该结构体保存了线程运行时信息。
    比喻你可以改变线程优先级、线程堆栈值等等(SetThreadContext(.....)。
      

  14.   

    同意该观点,完全和你的操作系统和CPU有关系!
      

  15.   

    这就是宏观上“并行”或“同时”执行的,微观上是“串行”或“异步”执行的。
    按照programmer的要求写代码就可以了,os会帮你调度。
      

  16.   

    我的问题是:线程threadPro2->Wait Event,然后到线程threadPro1运行,当线程1给事件设置信号后线程又是怎么运行的?
    ============================================================================
    线程threadPro2和线程threadPro1同时运行。 
      

  17.   

    http://www.yatio.com顶一下!
      

  18.   

    免费视频:
    浪曦ASP.NET企业实战系列 http://down1.langsin.com/001.rar
    浪曦NUnit详解视频 http://down1.langsin.com/002.rar
    浪曦Struts 2应用开发详解 http://www.verycd.com/topics/210454
    VIP视频:
    浪曦Java常见笔试、面试题目深度剖析 http://down1.langsin.com/003.rar
    浪曦J2EE测试实用指南http://down1.langsin.com/005.rar
    浪曦Lucene视频教程 http://down1.langsin.com/006.rar
    浪曦电脑维护项目 http://down1.langsin.com/007.rar
    培训视频:
    浪曦ExtJS视频之Grid控件 http://down1.langsin.com/008.rar
    业务QQ:1050429531
      

  19.   


    使当前线程创建了一个挂起的线程,如果在它cpu时间片用完前执行了ResumeThread,那么效果和直接创建一个立即运行的线程是完全一样的。 
    这里有点不大明白,假如创建并挂起的线程前面还有别的线程等待呢?
      

  20.   

    LSD,是不是要考虑优先级了呢?学习中~~~
      

  21.   

    对Windows内核对象的等待,不会是采用轮询的方式,此时该线程不会被调度。当一个内核对象被设置后,设置线程会触发CPU软中断,如果是在多核平台上,Windows任务调度模块可能会立即捕获到CPU软中断,会首先判断哪个事件被触发了,将等待该事件的所有线程设置成可调度状态,但接下来不一定就会立即调度该线程,可能会临时提升优先级。任务调度模块的优先级是很高的,在多线程切合之前会不停地调用,获中断信息,进行任务调度等操作。
      

  22.   

    楼主应该把pv操作弄清楚,这个题是关于pv的
      

  23.   

    看大家的帖子又学到不少东西,基本多线程就是这种情况,setevent后,线程二才有机会继续往下面执行。
      

  24.   

    软件架构QQ群 群号76395176软件架构,UML,开发语言不限,架构是主题,软件一般问题也鼓励讨论,情感交流
    工作经验5年以上,年令30以上
      

  25.   

    //有这样两个线程:HANDLE m_event = NULL:void threadPro1(...)
    {
    ...
    SetEvent(m_event);
    ...
    }void threadPro2(...)
    {
    ...
    WaitForSingleObject(m_event,INFINITE);
    ResetEvent((m_event);
    ...
    }
    //如果开始时是threadPro2线程处于运行状态,那么CPU对threadPro1和threadPro2是怎么调度的?
    我的问题是:线程threadPro2->Wait Event,然后到线程threadPro1运行,当线程1给事件设置信号后线程又是怎么运行的?


    因为线程threadPro2先执行,当执行到WaitForSingleObject(m_event,INFINITE);命令时,如果m_event出入无信号状态,参数INFINITE决定了这个线程必须一直等待,直到m_event处于有信号状态。os会将这个线程挂起,放入到等待队列中。假如经过了若干个时间片后,threadPro1得到了运行机会,通过SetEvent(m_event);告知os,m_event这个内核对象被激活了,os此时就会将等待m_event而阻塞的线程放入就绪队列中,os会根据调度算法将cpu分配给某个就绪队列中的线程。调度算法请自行查阅资料。
    问题二:
    [color=#0000FF]  当在一个线程内创建一个新的线程时,如果创建的新线程是创建后立即执行和创建后挂起,然后紧接着就ResumeThread该线程,那么这两种方式的区别(操作系统在线程调度上的区别)。
    呵呵,这个问题其实和上面那个问题是一样的,新线程创建后立即执行并不是说这个线程立即得到cpu,而是说这个线程被放入就绪队列中,一旦这个线程获得了cpu就能立即执行。而创建后挂起,紧接着执行就要看父线程是否有机会执行ResumeThread,如果有机会的话,应该没有什么区别。[/color]