3

作为一个附带项目,我正在实现一个 MIDI 矩阵,以将多个 MIDI 键盘与声源互连。这里的关键要求是将输入端口上接收到的 MIDI 数据回显到选定的输出端口。

创建了必要的 P/Invoke 声明和包装器后,我注意到 Win32 MIDI 文档的MidiInProc状态:“应用程序不应从回调函数内部调用任何多媒体函数,因为这样做会导致死锁”。鉴于从内部

调用是不安全的,我当前的解决方案是将 MIDI 数据写入队列并设置事件。工作线程等待事件并调用. 总体思路是这样的:-midiOutShortMsgMidiInProcmidiOutShortMsg

static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
    if( wMsg == MM_MIM_DATA )
    {
        data.EnQueue( dwParam1 );       //data is a Queue<uint>
        dataReady.Set();            //dataReady is AutoResetEvent
    }
}


void ThreadProc
{
    while( !_done )
    {
        dataReady.WaitOne();
        midiOutShortMsg( hMidiOut, data.DeQueue() );
    }
}

dataReady.Set()然而,虽然这在测试中运行良好,但在调用和返回之间似乎存在一个机会窗口,在此InputCallBack期间抢占可以允许工作线程调用midiOutShortMsg(尽管在另一个线程中)。

这种方法安全吗?

4

2 回答 2

3

对我来说看起来很安全:即使你的两个线程同时运行,它仍然只有工作线程可能会阻塞,所以这不会死锁你的输入回调。

于 2009-09-21T12:42:49.830 回答
1

对于 StackOverflow,您的问题可能有点特定于域。如果这里没有人回答,请查看: http ://groups.google.com/group/mididev?hl=en&lnk=

于 2009-09-21T12:38:09.047 回答