求问关于线程的问题 如何才能激活线程呢

eaglewxy   2008-8-6 16:50 楼主
在一个函数中定义一个线程
m_dwThreadId=0
m_hThread = CreateThread( NULL, 0, CGraphManager::ThreadProc, this, 0, &m_dwThreadId );

具体函数:
Init()
{
    HRESULT hr = S_OK;
        RETAILMSG(1,(L"CGraphManager::Init() \n"));
    // Create the event that will signal the thread for commands
    m_handle[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
        RETAILMSG(1,(L"CGraphManager::Init() L1\n"));
    if( m_handle[0] == NULL )
    {
                RETAILMSG(1,(L"CGraphManager::Init() L2\n"));
        ERR( HRESULT_FROM_WIN32( GetLastError() ));
    }
    m_handle[1] = 0;
        RETAILMSG(1,(L"CGraphManager::Init() L3\n"));
    // Create the event to sync on to wait for the command to be executed
    m_hCommandCompleted = CreateEvent( NULL, FALSE, FALSE, NULL );
        RETAILMSG(1,(L"CGraphManager::Init() L4\n"));
    if( m_hCommandCompleted == NULL )
    {
        ERR( HRESULT_FROM_WIN32( GetLastError() ));
    }
        RETAILMSG(1,(L"CGraphManager::Init() L5\n"));
    // CCreate the thread that will run the filtergraph.
       m_hThread = CreateThread( NULL, 0, CGraphManager::ThreadProc, this, 0, &m_dwThreadId );
        RETAILMSG(1,(L"CGraphManager::Init() L6\n"));
    if( m_hThread == NULL )
    {
        ERR( HRESULT_FROM_WIN32( GetLastError() ));
    }


Cleanup:
    return hr;
}

DWORD WINAPI  ThreadProc( LPVOID lpParameter )
{
    HRESULT       hr = S_OK;
    DWORD         dwReturnValue;
    CGraphManager *pThis = (CGraphManager*) lpParameter;
    GRAPHCOMMANDS command = COMMAND_NOCOMMAND;
        RETAILMSG(1,(L"CGraphManager::ThreadProc() started\n"));
    if( pThis == NULL )
    {
        return 0;
    }

    while(( command != COMMAND_SHUTDOWN ) && ( hr != S_FALSE ))
    {
        dwReturnValue = WaitForMultipleObjects( 2, pThis->m_handle, FALSE, INFINITE );
                RETAILMSG(1,(L"*********CGraphManager::ThreadProc() ::WaitForMultipleObjects********\n"));
        switch( dwReturnValue )
        {
            case WAIT_OBJECT_0:
                command = pThis->m_currentCommand;
                pThis->ProcessCommand();
                break;

            case WAIT_OBJECT_0 + 1:
                pThis->ProcessDShowEvent();
                break;

            default:
                break;
        }
    };
        RETAILMSG(1,(L"CGraphManager::ThreadProc() is  finished\n"));
    return 0;
}

但是我看到第一次执行Init()函数的时候并没有执行ThreadProc()函数,ThreadProc()函数是通过其他函数激发的,但是有一个很不明白的问题,我看到激发的函数:
BuildCaptureGraph()
{
        RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph() \n"));
    // The Graph is built on a separate thread to
    // prevent reentrancy issues.
    m_currentCommand = COMMAND_BUILDGRAPH;
    SetEvent( m_handle[0] );
RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph() after SetEvent \n")); //执行完这句激发ThreadProc
    WaitForSingleObject( m_hCommandCompleted, INFINITE );
        RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph() end \n"));
    return S_OK;
}

在BuildCaptureGraph()函数中的中文注释可以看到,这里并没有做什么东西,为什么就能激发ThreadProc()呢?
很是奇怪

谢谢  ThreadProc()函数是怎么激发的啊

回复评论 (7)

ThreadProc()等待这两个事件
dwReturnValue = WaitForMultipleObjects( 2, pThis->m_handle, FALSE, INFINITE );
BuildCaptureGraph()
SetEvent( m_handle[0] ) 设置了其中的一个事件,所以ThreadProc()就被激发了
点赞  2008-8-6 22:50
事件是线程激发的原因,LZ仔细研究一下事件吧
点赞  2008-8-7 08:58

4楼 car 



同意2楼,研究一下事件和线程吧。

线程是在等待事件触发,事件由pThis->m_handle定义。
WaitForMultipleObjects( 2, pThis->m_handle, FALSE, INFINITE );

pThis->m_handle是数组,其中第一个被初始化为false。

BuildCaptureGraph中,
SetEvent( m_handle[0] );  就把第一个事件设为true了。

此时线程中的
WaitForMultipleObjects,就被激活,线程开始继续工作。
点赞  2008-8-7 09:31
引用: 引用 3 楼 lenux 的回复:


同意2楼,研究一下事件和线程吧。

线程是在等待事件触发,事件由pThis->m_handle定义。
WaitForMultipleObjects( 2, pThis->m_handle, FALSE, INFINITE );

pThis->m_handle是数组,其中第一个被初始化为false。

BuildCaptureGraph中,
SetEvent( m_handle[0] );  就把第一个事件设为true了。

此时线程中的
WaitForMultipleObjects,就被激活,线程开始继续工作。



这个我好像看到过 问题就是  你看函数

BuildCaptureGraph()
{
RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph() \n"));
    // The Graph is built on a separate thread to
    // prevent reentrancy issues.
    m_currentCommand = COMMAND_BUILDGRAPH;
    SetEvent( m_handle[0] );
RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph()after SetEvent \n"));//执行完这句激发ThreadProc
    WaitForSingleObject( m_hCommandCompleted, INFINITE );
RETAILMSG(1,(L"CGraphManager::BuildCaptureGraph() end \n"));
    return S_OK;
}


为什么不是一SetEvent(m_handle[0] ) 就马上激活ThreadProc 呢?? 而是要打印之后 在
WaitForSingleObject()另外一个事件之前才激活呢?

按照你们的说法 应该是 SetEvent()就激活,而不会先打印 然后再调用ThreadProc ()函数啊
点赞  2008-8-7 16:49
这个理论上是这样的啊。

具体实现就要看cpu的分配了。
要是cpu分配给了那个线程,就能马上开始做
WaitForMultipleObjects( 2, pThis->m_handle, FALSE, INFINITE );
后的代码。

点赞  2008-8-7 17:05
Reallyu      2008年08月08日 13点14分27秒 说:
创建线程的时候调用CreateThread fdwCreate参数可以选择让其立即执行,还是挂起
如果是立即执行,线程会立刻执行.如果是挂起需要调用ResumeThread使其恢复执行状态
但是你的程序里 线程 中调用了 WaitForMultiObject 挂起自身,这个函数需要他等待的事件触发(变成signaled),才会恢复向下执行
点赞  2008-8-18 15:19
说的没错。
但是你的代码中对fdwCreate 这个参数设置的是0.意味着线程马上运行。
点赞  2008-8-18 17:35
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复