WaitForSingleObject和线程的陌生性 [英] WaitForSingleObject and thread strangeness

查看:136
本文介绍了WaitForSingleObject和线程的陌生性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在COM Dll插件中有代码,该插件可将MIDI sysex运出到Midi设备.
由于sysex转储的大小很大,而且执行时间很长,因此我创建了一个线程来完成工作.历史上我使用_beginthread来使线程继续运行,但是最近发现有必要知道线程何时完成,所以我切换到_beginthreadex,因为它可以将句柄返回给WaitForSingleObject可以使用的已启动线程.
主要代码将4个32字的数组塞满了数据,线程最终将对其进行暴力破解,从而更改了全局数组中的字节,该数组或多或少是sysex转储模板",线程将使用数组中的字节进行修改. >
数据的实际Midi传输是最耗时的.每次调用myMidiOut-> MidiOutLongMessage大约需要1/2秒.此时,我会受到主机应用程序"Sonar"的支配,因为它会将sysex midi字符串发送出去.

当我从_beginthread(有效)切换到_beginthreadex时,乐趣开始了.

线程是这样启动的:

Hi,

I have code in a COM Dll plug-in that trucks out MIDI sysex to a midi device.
Because of the large size of the sysex dump and the time it takes to execute I created a thread to do the work. Historically I was using _beginthread to get the thread going but recently found it necessary to know when the thread was finished so I switched over to _beginthreadex as it can return a handle to the started thread that WaitForSingleObject can use.

The main code stuffed 4 32 word arrays with data that the thread will ultimately brute force change the bytes in a global array that is more or less a sysex dump "template" that the thread will modify with the bytes in the arrays.

The Actual midi transmission of the data is what takes the most time. About a 1/2 second for each call to myMidiOut->MidiOutLongMessage. At such time I am at the mercy of the host application "Sonar" as it sends the sysex midi string out.

When I switched from _beginthread (which worked), to _beginthreadex fun began.

The thread is started like this:

HANDLE hThread;
hThread = (HANDLE)_beginthreadex( NULL, 0,
CBCRMaster::SetKnobLed, m_pMidiOut, 0, NULL);  

hThread =(HANDLE) _beginthread(CBCRMaster::SetKnobLed,0,m_pMidiOut);

	switch (WaitForSingleObject(hThread, INFINITE))
	{
	     case WAIT_OBJECT_0 :
	     {
        	break;
	     }
	     case WAIT_TIMEOUT :
	     {
		TerminateThread(hThread, 0);
		break;
	     }
	        default :
	     {

		TerminateThread(hThread, 0);
		break;
	    }
        }



线程代码:数据数组由主代码填充. WorkLoad是填充到数组中的数据量.



The Thread Code: The data arrays are stuffed by the main code. WorkLoad is the amount of data stuffed in the arrays.

unsigned int WINAPI CBCRMaster::SetKnobLed(void * m_pMidiOut)
{

ISonarMidiOut * myMidiOut;
myMidiOut = (ISonarMidiOut*)m_pMidiOut;

while(WorkLoad > -1)
		
{

//.... Run through Sysex_SetEncoder[WorkLoad] and modify the bytes as needed...
//..... code omitted for brevity..............................................

// Now truck the Sysex dump to the midi device
							myMidiOut->MidiOutLongMsg((IControlSurface*)SurfaceAddress[0],sizeof(Sysex_SetEncoder),Sysex_SetEncoder);

WorkLoad--;  

}

return 0;
}




现在的问题:

如果开关(WaitForSingleObject(hThread,INFINITE))代码到位,则当线程到达myMidiOut-> MidiOutLongMessage代码时,它将永远不会执行另一行代码,调试器的作用就像线程进入杂草一样.
Sysex转储也不会发送到接收设备.

如果我注释掉整个开关(WaitForSingleObject(hThread,INFINITE))块并继续进行卡车运输,则Thread将按应有的方式执行,但我永远不知道它何时完成.

但是...如果我保留(WaitForSingleObject(hThread,INFINITE))块以执行,但注释掉myMidiOut-> MidiOutLongMessage行,则该线程将按预期运行,此外,WaitForSingleObject事件将以WAIT_OBJECT_0触发. >
我将堆栈从0增加到30毫无用处,我应该重申,整个shotin''搭配使用_beginthread都有效.

谢谢.

:Ron




Now the problem:

If the switch (WaitForSingleObject(hThread, INFINITE)) code is in place, when the thread gets to the myMidiOut->MidiOutLongMessage code it never then will execute another line of code, the debugger just acts as if the thread went into the weeds.
The Sysex dump is never sent to the receiving device either.

If I comment out the entire switch (WaitForSingleObject(hThread, INFINITE)) block and just keep on trucking, the Thread executes as it should but I never get to know when it is finished.

However... If I leave the (WaitForSingleObject(hThread, INFINITE)) block in to execute, but comment out the myMidiOut->MidiOutLongMessage line then the thread runs as it should and furthermore the WaitForSingleObject event fires with WAIT_OBJECT_0.

I have tied increasing the stack from 0 to 30 with no avail and I should reiterate that the whole shootin'' match worked with _beginthread.

Thanks.

:Ron

推荐答案

今年早些时候,我遇到了类似的问题.

您只需要在do循环中和循环内部调用不带开关的WaitForSingleObject即可,窥视消息泵并等待WAIT_OBJECT_0或其他消息.

这只是我试图传达的视觉效果,不会粘贴并为您工作.我使用了MultpleObject和CreateThread,但是这个概念有点相似.

但是当线程完成后,它将正常退出并通知您.

I had a similar problem, earlier in the year.

You have to just call the WaitForSingleObject without the switch, in a do loop, and inside the loop, take a peek at the message pump and wait for WAIT_OBJECT_0 or some other message.

This is just a visual concept of what I trying to convey, and will not paste and work for you. I used the MultpleObject and for CreateThread, but the concept is sort of similar.

But when the thread is done, it will exit gracefully and let you know about it.

DWORD dwRet;
do
{
	dwRet = ::MsgWaitForMultipleObjects(1, &hThread, FALSE, 
			INFINITE, QS_ALLINPUT);

	if (dwRet != WAIT_OBJECT_0)
	{
		MSG msg;
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));


谢谢.

我尝试了您的建议,对其进行了修改以使其与我的代码一起播放,如图所示,但它停留在dwRet = :: WaitForSingleObject(hThread,INFINITE);处.行,并且永远不会下降到if(dwRet!= WAIT_OBJECT)行.


Thank you.

I tried what you have suggested, modifying it to play with my code as shown but it sticks at the dwRet = ::WaitForSingleObject(hThread, INFINITE); line and never drops down to the if(dwRet != WAIT_OBJECT) line.


DWORD dwRet;
do
{
	dwRet = ::WaitForSingleObject(hThread, INFINITE);

	if (dwRet != WAIT_OBJECT_0)
	{
	        MSG msg;
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));


是的,它的工作量不大,因为现在代码会掉入,但是该线程仍然在myMidiOut->处进入杂草".因此永远不会发出信号.
如果我将这一行注释掉,则所有工作都按预期进行.

好像在我正在运行的环境中,该环境是将COM Dll插件插入较大的应用程序中一样,不允许以某种方式或其他方式使用WaitForANYTYPEofObject.

myMidiOut是属于所插入APP的对象.

感谢您在此方面的所有帮助.

我要喃喃自语一会儿..........
Yes, that worked insomuch as now the code will fall through but the thread still goes "into the weeds" at myMidiOut-> and therefore never signals it''s end.
If I comment this line out, all works as expected.

It''s as if in the environment I am running in which is a COM Dll plug-in into a larger application, that somehow or another WaitForANYTYPEofObject is not permitted.

The myMidiOut is an object that belongs to the APP in plugged into.

Thanks for all your help on this.

I''m going to go mutter to myself for a while..........


这篇关于WaitForSingleObject和线程的陌生性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆