如果在子线程里调用了SetTimer,那么回调函数的执行是在子线程里?
31 个解决方案
#1
回调函数是全局的和线程没关系.
#2
但是总属于某个进程/线程来执行的吧,如果回调访问程序里的资源,是否要做互斥呢
#3
lz的假设完全正确
#4
时间器只跟窗口有关。
#5
timer应该和线程无关,是系统调用的
#6
"时间器只跟窗口有关"
如果::SetTimer的窗口句柄设为NULL呢
"timer应该和线程无关,是系统调用的"
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
如果是在程序所运行的进程中,那么在进程中的哪个线程,是SetTimer调用者所在的线程吗?
如果是在调用者所在的线程,那么若调用者所在的线程退出了,那么回调还能发生吗?会出错吗?
如果::SetTimer的窗口句柄设为NULL呢
"timer应该和线程无关,是系统调用的"
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
如果是在程序所运行的进程中,那么在进程中的哪个线程,是SetTimer调用者所在的线程吗?
如果是在调用者所在的线程,那么若调用者所在的线程退出了,那么回调还能发生吗?会出错吗?
#7
加点分,欢迎高手解答
#8
关注
#9
虽然是系统调用的,但是当前进程会阻塞到OnTimer返回为止
为了能够异步调用,最好是在回调中建立一个线程,然后立即返回
为了能够异步调用,最好是在回调中建立一个线程,然后立即返回
#10
大致分析一下Winmain或者WinProc之类,就可以得出一个比较直接的结论
#11
摘自MSDN,SetTimer函数
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
由上文知,回调函数是在window procedure中调用的,而且它也是对消息WM_TIMER的处理时才调用的,所以它是在窗口线程中执行的,如果回调函数执行时间很长,会使消息线程阻掉,造成窗口死掉。
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
由上文知,回调函数是在window procedure中调用的,而且它也是对消息WM_TIMER的处理时才调用的,所以它是在窗口线程中执行的,如果回调函数执行时间很长,会使消息线程阻掉,造成窗口死掉。
#12
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
timer其实是一个内核对象,也就是说可以跨进程的.但是如果引用它的进程关闭了,timer也会被删除.
回调函数可以说是独立于进程里面的线程的,ontimer就不是很清楚了,要看mfc的实现.
timer其实是一个内核对象,也就是说可以跨进程的.但是如果引用它的进程关闭了,timer也会被删除.
回调函数可以说是独立于进程里面的线程的,ontimer就不是很清楚了,要看mfc的实现.
#13
说错了,应该是由settimer所在线程调用的
#14
向窗口注册了的Timer是由主窗口处理函数所在线程执行
没注册窗口句柄的Timer是由系统线程执行.
没注册窗口句柄的Timer是由系统线程执行.
#15
可以在OnTimer里Sleep()做实验
#16
内核对象timer的回调是由settimer所在线程调用的
#17
归纳一下大家的意见,把问题挖掘到底
如果是注册窗口的,则在窗口消息处理线程中执行,此时可能是在主线程中,也可以在用户界面子线程中,取决于该窗口消息处理所在的线程;
(问题:假设我创建的是用户界面子线程,然后在主线程中调用SetTimer将回调注册到该子线程中,那么调用SetTimer所运行的线程和回调函数所运行的就不是一个线程喽?)
如果没有注册窗口的,则是在调用SetTimer所在的线程中运行,此时与回调函数所在的线程是同一个线程。
(这里有人说回调是在系统线程中进行,到底什么是系统线程?)
如果是注册窗口的,则在窗口消息处理线程中执行,此时可能是在主线程中,也可以在用户界面子线程中,取决于该窗口消息处理所在的线程;
(问题:假设我创建的是用户界面子线程,然后在主线程中调用SetTimer将回调注册到该子线程中,那么调用SetTimer所运行的线程和回调函数所运行的就不是一个线程喽?)
如果没有注册窗口的,则是在调用SetTimer所在的线程中运行,此时与回调函数所在的线程是同一个线程。
(这里有人说回调是在系统线程中进行,到底什么是系统线程?)
#18
mark
#19
学习
#20
测试了一下,有如下现象:
1.在子线程中以无窗口SetTimer,回调函数仍然在子线程中被调用。
2.如果子线程没有消息循环,则回调函数始终不会被调用。
3.如果子线程只GetMessage不DispatchMessage,回调函数也不会被调用。
4.但在回调函数的堆栈中没有发现DispatchMessage入口。
结论是:
回调的执行与SetTimer是同样的线程,可以近似认为是由DispatchMessage这句话调用它(但不是直接调用)
1.在子线程中以无窗口SetTimer,回调函数仍然在子线程中被调用。
2.如果子线程没有消息循环,则回调函数始终不会被调用。
3.如果子线程只GetMessage不DispatchMessage,回调函数也不会被调用。
4.但在回调函数的堆栈中没有发现DispatchMessage入口。
结论是:
回调的执行与SetTimer是同样的线程,可以近似认为是由DispatchMessage这句话调用它(但不是直接调用)
#21
Timer事件是在消息队列的处理函数DispatchMessage中被调用的,消息队列是跟线程相关的,每个线程都拥有一个独立的消息队列,在哪个线程创建的Timer就会在哪个线程激发Timer事件,所以楼主的猜想是正确的。具体可参阅《Windows核心编程》
#22
学到点东西.我之前想当然的说,没想到线程消息循环的问题.
#23
学习一下
#24
谢谢大家,结帐
#25
谁创建,谁释放
#26
最后问一下:
若开辟了一个界面线程A,然后在主线程B上调用了A的方法,A方法中调用了SetTimer,窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧;
若调用SetTimer时窗口句柄设为NULL,那么回调是在主线程B上执行的吧?
若开辟了一个界面线程A,然后在主线程B上调用了A的方法,A方法中调用了SetTimer,窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧;
若调用SetTimer时窗口句柄设为NULL,那么回调是在主线程B上执行的吧?
#27
"窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧"
这个经测试通过
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
这个经测试通过
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
#28
#29
嗯,我自己编写了一个测试程序,证实了上面的观点,即:
若SetTimer传入的窗口句柄为NULL,则回调在调用SetTimer的线程上运行;
若传入的窗口句柄不为NULL,则回调在拥有窗口句柄的线程上运行,此时,调用SetTimer的线程和拥有窗口句柄的线程可以是同一个线程,也可以是不同线程
若SetTimer传入的窗口句柄为NULL,则回调在调用SetTimer的线程上运行;
若传入的窗口句柄不为NULL,则回调在拥有窗口句柄的线程上运行,此时,调用SetTimer的线程和拥有窗口句柄的线程可以是同一个线程,也可以是不同线程
#30
“ 回复人:lxinjing1234() () 信誉:100 2006-12-30 10:27:13
http://www.nud8.com/mlm/?mid=ownmoney ”
不要在这里做广告!!
http://www.nud8.com/mlm/?mid=ownmoney ”
不要在这里做广告!!
#31
“
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
”
但是,这要看调用SetTimer时传入的窗口句柄是否为NULL,是NULL,则哪个线程调用SetTimer,就在哪个线程回调,无论回调代码和SetTimer代码在哪里;如果句柄不为NULL,则一定是在拥有该窗口句柄的线程里回调,也无论回调代码和SetTimer代码在哪里。
这个是经我测验得到的结论
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
”
但是,这要看调用SetTimer时传入的窗口句柄是否为NULL,是NULL,则哪个线程调用SetTimer,就在哪个线程回调,无论回调代码和SetTimer代码在哪里;如果句柄不为NULL,则一定是在拥有该窗口句柄的线程里回调,也无论回调代码和SetTimer代码在哪里。
这个是经我测验得到的结论
#1
回调函数是全局的和线程没关系.
#2
但是总属于某个进程/线程来执行的吧,如果回调访问程序里的资源,是否要做互斥呢
#3
lz的假设完全正确
#4
时间器只跟窗口有关。
#5
timer应该和线程无关,是系统调用的
#6
"时间器只跟窗口有关"
如果::SetTimer的窗口句柄设为NULL呢
"timer应该和线程无关,是系统调用的"
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
如果是在程序所运行的进程中,那么在进程中的哪个线程,是SetTimer调用者所在的线程吗?
如果是在调用者所在的线程,那么若调用者所在的线程退出了,那么回调还能发生吗?会出错吗?
如果::SetTimer的窗口句柄设为NULL呢
"timer应该和线程无关,是系统调用的"
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
如果是在程序所运行的进程中,那么在进程中的哪个线程,是SetTimer调用者所在的线程吗?
如果是在调用者所在的线程,那么若调用者所在的线程退出了,那么回调还能发生吗?会出错吗?
#7
加点分,欢迎高手解答
#8
关注
#9
虽然是系统调用的,但是当前进程会阻塞到OnTimer返回为止
为了能够异步调用,最好是在回调中建立一个线程,然后立即返回
为了能够异步调用,最好是在回调中建立一个线程,然后立即返回
#10
大致分析一下Winmain或者WinProc之类,就可以得出一个比较直接的结论
#11
摘自MSDN,SetTimer函数
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
由上文知,回调函数是在window procedure中调用的,而且它也是对消息WM_TIMER的处理时才调用的,所以它是在窗口线程中执行的,如果回调函数执行时间很长,会使消息线程阻掉,造成窗口死掉。
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
由上文知,回调函数是在window procedure中调用的,而且它也是对消息WM_TIMER的处理时才调用的,所以它是在窗口线程中执行的,如果回调函数执行时间很长,会使消息线程阻掉,造成窗口死掉。
#12
系统回调程序里的代码时,到底是运行在程序所运行的进程中,还是有一个系统进程?
timer其实是一个内核对象,也就是说可以跨进程的.但是如果引用它的进程关闭了,timer也会被删除.
回调函数可以说是独立于进程里面的线程的,ontimer就不是很清楚了,要看mfc的实现.
timer其实是一个内核对象,也就是说可以跨进程的.但是如果引用它的进程关闭了,timer也会被删除.
回调函数可以说是独立于进程里面的线程的,ontimer就不是很清楚了,要看mfc的实现.
#13
说错了,应该是由settimer所在线程调用的
#14
向窗口注册了的Timer是由主窗口处理函数所在线程执行
没注册窗口句柄的Timer是由系统线程执行.
没注册窗口句柄的Timer是由系统线程执行.
#15
可以在OnTimer里Sleep()做实验
#16
内核对象timer的回调是由settimer所在线程调用的
#17
归纳一下大家的意见,把问题挖掘到底
如果是注册窗口的,则在窗口消息处理线程中执行,此时可能是在主线程中,也可以在用户界面子线程中,取决于该窗口消息处理所在的线程;
(问题:假设我创建的是用户界面子线程,然后在主线程中调用SetTimer将回调注册到该子线程中,那么调用SetTimer所运行的线程和回调函数所运行的就不是一个线程喽?)
如果没有注册窗口的,则是在调用SetTimer所在的线程中运行,此时与回调函数所在的线程是同一个线程。
(这里有人说回调是在系统线程中进行,到底什么是系统线程?)
如果是注册窗口的,则在窗口消息处理线程中执行,此时可能是在主线程中,也可以在用户界面子线程中,取决于该窗口消息处理所在的线程;
(问题:假设我创建的是用户界面子线程,然后在主线程中调用SetTimer将回调注册到该子线程中,那么调用SetTimer所运行的线程和回调函数所运行的就不是一个线程喽?)
如果没有注册窗口的,则是在调用SetTimer所在的线程中运行,此时与回调函数所在的线程是同一个线程。
(这里有人说回调是在系统线程中进行,到底什么是系统线程?)
#18
mark
#19
学习
#20
测试了一下,有如下现象:
1.在子线程中以无窗口SetTimer,回调函数仍然在子线程中被调用。
2.如果子线程没有消息循环,则回调函数始终不会被调用。
3.如果子线程只GetMessage不DispatchMessage,回调函数也不会被调用。
4.但在回调函数的堆栈中没有发现DispatchMessage入口。
结论是:
回调的执行与SetTimer是同样的线程,可以近似认为是由DispatchMessage这句话调用它(但不是直接调用)
1.在子线程中以无窗口SetTimer,回调函数仍然在子线程中被调用。
2.如果子线程没有消息循环,则回调函数始终不会被调用。
3.如果子线程只GetMessage不DispatchMessage,回调函数也不会被调用。
4.但在回调函数的堆栈中没有发现DispatchMessage入口。
结论是:
回调的执行与SetTimer是同样的线程,可以近似认为是由DispatchMessage这句话调用它(但不是直接调用)
#21
Timer事件是在消息队列的处理函数DispatchMessage中被调用的,消息队列是跟线程相关的,每个线程都拥有一个独立的消息队列,在哪个线程创建的Timer就会在哪个线程激发Timer事件,所以楼主的猜想是正确的。具体可参阅《Windows核心编程》
#22
学到点东西.我之前想当然的说,没想到线程消息循环的问题.
#23
学习一下
#24
谢谢大家,结帐
#25
谁创建,谁释放
#26
最后问一下:
若开辟了一个界面线程A,然后在主线程B上调用了A的方法,A方法中调用了SetTimer,窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧;
若调用SetTimer时窗口句柄设为NULL,那么回调是在主线程B上执行的吧?
若开辟了一个界面线程A,然后在主线程B上调用了A的方法,A方法中调用了SetTimer,窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧;
若调用SetTimer时窗口句柄设为NULL,那么回调是在主线程B上执行的吧?
#27
"窗口句柄使用了界面线程A的句柄,则回调是在界面线程A上运行吧"
这个经测试通过
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
这个经测试通过
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
#28
#29
嗯,我自己编写了一个测试程序,证实了上面的观点,即:
若SetTimer传入的窗口句柄为NULL,则回调在调用SetTimer的线程上运行;
若传入的窗口句柄不为NULL,则回调在拥有窗口句柄的线程上运行,此时,调用SetTimer的线程和拥有窗口句柄的线程可以是同一个线程,也可以是不同线程
若SetTimer传入的窗口句柄为NULL,则回调在调用SetTimer的线程上运行;
若传入的窗口句柄不为NULL,则回调在拥有窗口句柄的线程上运行,此时,调用SetTimer的线程和拥有窗口句柄的线程可以是同一个线程,也可以是不同线程
#30
“ 回复人:lxinjing1234() () 信誉:100 2006-12-30 10:27:13
http://www.nud8.com/mlm/?mid=ownmoney ”
不要在这里做广告!!
http://www.nud8.com/mlm/?mid=ownmoney ”
不要在这里做广告!!
#31
“
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
”
但是,这要看调用SetTimer时传入的窗口句柄是否为NULL,是NULL,则哪个线程调用SetTimer,就在哪个线程回调,无论回调代码和SetTimer代码在哪里;如果句柄不为NULL,则一定是在拥有该窗口句柄的线程里回调,也无论回调代码和SetTimer代码在哪里。
这个是经我测验得到的结论
"然后在主线程B上调用了A的方法,A方法中调用了SetTimer"
A方法如果是在主线程B上调用,那么也就相当于在主线程上调用SetTimer了,所以这个实际上和我们原来讨论的是一样的。
”
但是,这要看调用SetTimer时传入的窗口句柄是否为NULL,是NULL,则哪个线程调用SetTimer,就在哪个线程回调,无论回调代码和SetTimer代码在哪里;如果句柄不为NULL,则一定是在拥有该窗口句柄的线程里回调,也无论回调代码和SetTimer代码在哪里。
这个是经我测验得到的结论