谢谢,最好是资料或者是文章,谢谢了!!!急急急!!!

解决方案 »

  1.   

    MSDN是你身边最好的帮手!!!
    最常用的是:_beginthread,_endthread,_abord,_exit等
    下面的例子取自MSDN:
    Example/* BEGTHRD.C illustrates multiple threads using functions:
     *
     *      _beginthread            _endthread
     *
     *
     * This program requires the multithreaded library. For example,
     * compile with the following command line:
     *     CL /MT /D "_X86_" BEGTHRD.C
     *
     * If you are using the Visual C++ development environment, select the 
     * Multi-Threaded runtime library in the compiler Project Settings 
     * dialog box.
     * 
     */#include <windows.h>
    #include <process.h>    /* _beginthread, _endthread */
    #include <stddef.h>
    #include <stdlib.h>
    #include <conio.h>void Bounce( void *ch );
    void CheckKey( void *dummy );/* GetRandom returns a random integer between min and max. */
    #define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))BOOL repeat = TRUE;     /* Global repeat flag and video variable */
    HANDLE hStdOut;         /* Handle for console window */
    CONSOLE_SCREEN_BUFFER_INFO csbi;    /* Console information structure */void main()
    {
        CHAR    ch = 'A';    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );    /* Get display screen's text row and column information. */
       GetConsoleScreenBufferInfo( hStdOut, &csbi );    /* Launch CheckKey thread to check for terminating keystroke. */
        _beginthread( CheckKey, 0, NULL );    /* Loop until CheckKey terminates program. */
        while( repeat )
        {
            /* On first loops, launch character threads. */
            _beginthread( Bounce, 0, (void *) (ch++)  );        /* Wait one second between loops. */
            Sleep( 1000L );
        }
    }/* CheckKey - Thread to wait for a keystroke, then clear repeat flag. */
    void CheckKey( void *dummy )
    {
        _getch();
        repeat = 0;    /* _endthread implied */}/* Bounce - Thread to create and and control a colored letter that moves
     * around on the screen.
     *
     * Params: ch - the letter to be moved
     */
    void Bounce( void *ch )
    {
        /* Generate letter and color attribute from thread argument. */
        char    blankcell = 0x20;
        char    blockcell = (char) ch;
        BOOL    first = TRUE;
       COORD   oldcoord, newcoord;
       DWORD   result;
        /* Seed random number generator and get initial location. */
        srand( _threadid );
        newcoord.X = GetRandom( 0, csbi.dwSize.X - 1 );
        newcoord.Y = GetRandom( 0, csbi.dwSize.Y - 1 );
        while( repeat )
        {
            /* Pause between loops. */
            Sleep( 100L );        /* Blank out our old position on the screen, and draw new letter. */
            if( first )
                first = FALSE;
            else
             WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord, &result );
             WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord, &result );        /* Increment the coordinate for next placement of the block. */
            oldcoord.X = newcoord.X;
            oldcoord.Y = newcoord.Y;
            newcoord.X += GetRandom( -1, 1 );
            newcoord.Y += GetRandom( -1, 1 );        /* Correct placement (and beep) if about to go off the screen. */
            if( newcoord.X < 0 )
                newcoord.X = 1;
            else if( newcoord.X == csbi.dwSize.X )
                newcoord.X = csbi.dwSize.X - 2;
            else if( newcoord.Y < 0 )
                newcoord.Y = 1;
            else if( newcoord.Y == csbi.dwSize.Y )
                newcoord.Y = csbi.dwSize.Y - 2;        /* If not at a screen border, continue, otherwise beep. */
            else
                continue;
            Beep( ((char) ch - 'A') * 100, 175 );
        }
        /* _endthread given to terminate */
        _endthread();
    }
      

  2.   

    refer to : MSDN ;http://www.vckbase.com/code/listcode.asp?mclsid=13&sclsid=1305;http://www.codeproject.com/threads/
      

  3.   

    二, 线程的创建方法
    调用Win32 API中的CreateThread函数创建线程。
    hThread=CreateThread(NULL,0,&TEventWindow::ThreadFunc,this,0,&hThreadId);
    第一个参数设定线程的安全属性,因其仅用于Windows NT,故不设定。第二个参数为0
    指定线程使用缺省的堆栈大小。第三个参数指定线程函数,线程即从该函数的入口处开始
    运行,函数返回时就意味着线程终止运行。第四个参数为线程函数的参数,可以是指向任
    意数据类型的指针。第五个参数设定线程的生成标志。hThreadId存放线程的标识号。
    线程函数如下定义,上述的 this参数是指向线程所属窗口的句柄指针,通过thrdWin
    参数传送过来,利用这个指针再调用相应的LoopFunc函数,线程的具体事务都在这个函数
    中执行。
    DWORD _stdcall TEventWindow::ThreadFunc(void *thrdWin){ 
    return STATIC_CAST(TEventWindow*,thrdWin)->LoopFunc( );
    } 三, 线程的同步事件控制方法
    Windows 95提供两种基本类型的系统对象,一种是彼此互斥的对象,用来协调访问数
    据,如 mutex对象;一种是事件同步对象,用来发送命令或触发事件,安排事件执行的先
    后次序,如 event对象。系统对象在系统范围内有效,它们都具有自己的安全属性、访问
    权限和以下两种状态中的一种:Signaled和nonSignaled。对于event对象调用SetEvent函
    数可将其状态设为Signaled,调用ResetEvent函数则可将其状态设为nonSignaled。
    演示程序中的线程在一个大循环中不断地将运行结果显示出来,当用户要关闭窗口时
    线程才终止运行。不过必须在窗口关闭之前先终止线程的运行,否则线程运行的结果将会
    显示在屏幕的其他地方,所以有必要在线程结束与关闭窗口这两个事件之间建立起同步关
    系。为此在TEventWindow类的构造函数中创建两个event对象,用来实现事件同步。
    hCloseEvent=CreateEvent(0,FALSE,FALSE,0); 
    hNoCloseEvent=CreateEvent(0,FALSE,FALSE,0);
    第二个参数为FALSE 表示创建的是一个自动event对象,第三个参数为FALSE表示对象
    的初始状态为nonSignaled,第四个参数为0表示该对象没有名字。在TEventWindow类的构
    造函数中还同样创建hWatchEvent和hNtyEvent对象,初始状态都为nonSignaled。
    用户要关闭窗口时,程序首先调用CanClose 函数,在该函数中设置hCloseEvent对象
    的状态为Signaled,利用这个方法来通知线程,要求线程终止运行。然后主线程调用函数
    WaitForMultipleObjects(该函数以下简称wait函数 ),wait函数先判断对象hThread和
    hNoCloseEvent中任意一个的状态是否为Signaled, 如果都不是就堵塞主线程的运行,直
    到上述条件满足;如果有一个对象的状态为Signaled,wait函数就返回,不再堵塞主线程。
    如果对象是自动event对象,wait函数在返回之前还会将对象的状态设为nonSignaled。
    wait函数中的参数FALSE表示不要求两个对象的状态同时为Signaled,参数-1表示要
    无限期地等待下去直到条件满足,参数2表示SignalsC数组中有两个对象。在Windows 95
    中线程也被看作是一种系统对象,同样具有两种状态。线程运行时其状态为nonSignaled,
    如果线程终止运行,则其状态被系统自动设为Signaled( 可以通过线程的句柄hThread得
    到线程状态),此时wait函数返回0,表示第一个对象满足条件,于是CanClose返回TRUE
    表示窗口可以关闭;如果线程不能满足终止运行的条件,就设置hNoCloseEvent 对象的状
    态为Signaled,此时wait函数返回1,表示第二个对象满足条件,于是CanClose返回FALSE
    表示窗口暂时还不能关闭。
    BOOL TEventWindow::CanClose(){
    HANDLE SignalsC[2]={hThread,hNoCloseEvent};
    SetEvent(hCloseEvent);
    if(WaitForMultipleObjects(2,SignalsC,FALSE,-1)==0) return TRUE; 
    else return FALSE;
    }
    另一个用户控制的例子是,用户使主线程暂停运行直到线程满足某种条件为止。比如
    用户选择“Watch”菜单后,主线程调用如下函数开始对线程的运算数据进行监测。 首先
    设置hWatchEvent对象的状态为Signaled,以此来通知线程, 主线程此时已进入等待状态
    并开始对数据进行监测,然后主线程调用wait函数等待线程的回应。线程在满足某个条件
    后就设置hNtyEvent对象的状态为Signaled,使主线程结束等待状态,继续运行。
    void TEventWindow::CmWatch(){
    SetEvent(hWatchEvent);
    WaitForSingleObject(hNtyEvent,-1);
    ::MessageBox(GetFocus(),"线程已符合条件,主线程继续运行!","",MB_OK);
    }
    线程函数所调用的LoopFunc是一个大循环,它不断地判断同步对象的状态,并根据这
    些对象的状态执行相应的操作,这些对象在数组SignalsL中列出。在这个数组中各元素的
    排列顺序是很重要的,前两个对象分别对应两种不同的用户控制事件,通过判断对象的状
    态可以知道发生的是哪一种用户控制。只有当前面两个对象的状态都不是Signaled时才会
    判断第三个对象的状态,这样一方面保证线程能检测到所有的用户控制事件,另一方面又
    保证了在不发生用户控制事件时线程也能继续运行。为此特地在TEventWindow类的构造函
    数中创建的对象hNoBlockEvent的状态始终为Signaled。
    hNoBlockEvent=CreateEvent(0,TRUE,TRUE,"MyEvent");
    第二个参数为TRUE表示创建的是一个手工event对象, 其状态是不会被wait函数所改
    变的,除非显式地调用ResetEvent函数。第三个参数为TRUE表示对象初始状态为Signaled,
    第四个参数定义了该对象的名字为“MyEvent”。
    LoopFunc函数调用wait函数,如果检测到hCloseEvent的状态为Signaled, 此时wait
    函数返回0,线程知道用户要关闭窗口了,就判断线程是否可以终止,条件是iCount>100,
    如果满足终止条件LoopFunc函数就返回,实际上就终止了线程的运行;如果不满足条件线
    程就设置 hNoCloseEvent对象的状态为Signaled,让主线程知道线程暂时还不能终止。由
    于hCloseEvent是自动event对象,所以wait函数返回0时还会将对象hCloseEvent的状态设
    置为nonSignaled,这样在第二次循环时,wait函数就不会判断出hCloseEvent对象的状态
    为Signaled,避免了线程错误地再次去判断是否会满足终止条件。如果wait函数检测到对
    象hWatchEvent的状态为Signaled,此时wait函数返回1,线程知道主线程已进入等待状态
    并在对数据进行监测,就设置变量bWatch的值为TRUE。如果前面的两个事件都未发生,则
    前面两个对象的状态都为nonSignaled,于是wait函数就检测第三个对象的状态, 由于第
    三个对象hNoBlockEvent 的状态始终为Signaled,所以线程就无阻碍地继续运行下去,将
    变量iCount不断加一,当变量大于200时,如果bWatch为TRUE,就设置hNtyEvent的状态为
    Signaled,从而使主线程停止等待,继续运行。
    DWORD TEventWindow::LoopFunc(){
    HANDLE SignalsL[3]={hCloseEvent,hWatchEvent,hNoBlockEvent};
    static BOOL bWatch=false;int dwEvent;
    while(1){
    dwEvent=WaitForMultipleObjects(3,SignalsL,FALSE,-1);
    switch(dwEvent){
    case 0: if(iCount>100) return 0;
    else SetEvent(hNoCloseEvent);
    break;
    case 1: bWatch=TRUE;break;
    case 2: ++iCount;
    if(bWatch && iCount>200) SetEvent(hNtyEvent);
    break;
    }
    }
    }四, 进程间的多线程同步事件控制方法
    由于event对象是系统范围内有效的,所以另一个进程(即一个应用程序,本身也是一
    个线程)可调用OpenEvent函数,通过对象的名字获得对象的句柄, 但对象必须是已经创
    建的,然后可将这个句柄用于ResetEvent、SetEvent和WaitForMultipleObjects等函数中。
    这样可以实现一个进程的线程控制另一进程生成的线程的运行。如下面的语句就是通过对
    象名字“MyEvent”获得了上面进程生成的hNoBlockEvent对象的句柄,再使用这个句柄将
    对象状态设为nonSignaled。在上述的 LoopFunc函数中由于该对象的状态已经改变,使得
    上面的线程暂停运行。
    HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,true,"MyEvent"); 
    ResetEvent(hEvent); 
    OpenEvent函数的第一个参数表示函数的调用线程对event对象的访问权限,比如让线
    程拥有对象所有的访问权限,就选参数EV
      

  4.   

    <<Multithreading Applications in Win32>>
    Author: Jim Beveridge & Robert Winner中译本:<<Win32多线程程式设计>>
    作者:侯俊杰这本书对线程讲的比较详细,可以好好看看。