• (转)线程相关的东东


    1.C语言函数,调用_beginthread();

    2.API函数,调用CreateThread();(这个函数是_beginthread  和AfxBeginThread 根本 )

    3.MFC函数,调用AfxBeginThread();

    AfxBeginThread是MFC的全局函数,是对CreateThread的封装。

    CreateThread是Win32 API函数,AfxBeginThread最终要调到CreateThread。

    ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××
    1>.
    具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过

    程中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁的因素,用起来

    比较繁琐一些,初学的人在用到的时候可能会产生不可预料的错误,建议多使用AfxBeginThread,是编译

    器对原来的CreateThread函数的封装,用与MFC编程(当然,只要修改了项目属性,console和win32项目

    都能调用)而_beginthread是C的运行库函数。

    2>
    在使用AfxBeginThread时,
    线程函数的定义为:UINT _yourThreadFun(LPVOID pParam)参数必须如此

    在使用CreateThread时,
    线程的函数定义为: DWORD WINAPI _yourThreadFun(LPVOID pParameter)

    两者实质是一样的,
    不过AfxBeginThread返回CWinThread指针,就是说它会new一个CWinThread对象,而这个对象在线程运行结束时是会自动删除的,

    CreatThread,它返回的是一个句柄,如果你不使用CloseHandle的话就可以通过它安全的了解线程状态,

    最后不要的时候CloseHandle,Windows才会释放资源。

     _beginthreadex是微软的C/C++运行时库函数,CreateThread是操作系统的函数,_beginthreadex通过调用CreateThread来实现的,但比CreateThread多做了许多工作。

     ×××××××××××××××××××××××××××××××××××××

    利用MFC里的AfxBeginThread函数能很方便地创建线程以及对线程进行等待、唤醒等操作。
    1、函数原型
    CWinThread* AfxBeginThread//返回值:一个指向新线程的线程对象。

    (

    AFX_THREADPROC pfnThreadProc ,//线程的入口函数,声明一定要如下:UINT MyThreadFunction( LPVOID pParam );

    LPVOID pParam ,//传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程。

    int nPriority = THREAD_PRIORITY_NORMAL ,//线程的优先级,一般设置为 0。让它和主线程具有共同的优先级。

    UINT nStackSize = 0 ,//指定新创建的线程的栈的大小。如果为 0,新创建的线程具有和主线程一样的大小的栈。

    DWORD dwCreateFlags = 0,//指定创建线程以后,线程有怎么样的标志。可以指定两个值:

                          //CREATE_SUSPENDED:线程创建以后,会处于挂起状态,直到调用ResumeThread;

                          //0:创建线程后就开始运行。

    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL//指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性

                              // 如果为 NULL,那么新创建的线程就具有和主线程一样的安全性。 

    ); 

     线程创建
    一般创建过程如下:
    先定义一个工作函数,一般来说你的线程就是依照该函数的功能执行任务:
    UINT MyThreadFunction( LPVOID pParam )
    {
    //函数体
    return 0;
    }
    然后可以按以下方式创建线程:
    CWinThread* MyThread=AfxBeginThread(MyThreadFunction , pParam , THREAD_PRIORITY_NORMAL , 0 , 0 , NULL);
    4、线程的等待与唤醒
    (1)让线程等待(暂时挂起):
    MyThread->SuspendThread();
    (2)唤醒暂停的线程:
    MyThread->ResumeThread();
    5、查看线程状态:
    DWORD code;
    GetExitCodeThread(MyThread->m_hThread , &code);
    if(code==STILL_ACTIVE){//线程仍在执行}
    else {//线程停止执行}
    6、结束线程
    TerminateThread(MyThread->m_hThread , 0);

    ×××××××××××××××××××××××××××××

    CWinThread* AfxBeginThread

    (

    CRuntimeClass* pThreadClass,//工作线程的函数指针,不可以为空。并且工作线程的函数必须如此声明:

    int nPriority = THREAD_PRIORITY_NORMAL,

    UINT nStackSize = 0,

    DWORD dwCreateFlags = 0,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL

    );

    ×××××××××××××××××××××××××××××××××××××

     ××××××××××××××××××××××××××××××××××××××××××××××××××

    CreateThread

    函数功能:创建线程

    函数原型:

    HANDLEWINAPICreateThread(

        LPSECURITY_ATTRIBUTESlpThreadAttributes,//表示线程内核对象的安全属性,一般传入NULL表示使用默认设置

        SIZE_TdwStackSize,//表示线程栈空间大小。传入0表示使用默认大小(1MB)。

        LPTHREAD_START_ROUTINElpStartAddress,//表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。

        LPVOIDlpParameter,//传给线程函数的参数。

        DWORDdwCreationFlags,//指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,

                  // 如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。

        LPDWORDlpThreadId//返回线程的ID号,传入NULL表示不需要返回该线程ID号。

    );

    函数返回值:成功返回新线程的句柄,失败返回NULL。

    //最简单的创建多线程实例
    #include <stdio.h>
    #include <windows.h>
    //子线程函数
    DWORD WINAPI ThreadFun(LPVOID pM)
    {
        printf("子线程的线程ID号为:%d
    子线程输出Hello World
    ", GetCurrentThreadId());
        return 0;
    }
    //主函数,所谓主函数其实就是主线程执行的函数。
    int main()
    {
        printf("     最简单的创建多线程实例
    ");
        printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --
    
    ");
    
        HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
        WaitForSingleObject(handle, INFINITE);
        return 0;
    }

    ××××××××××××××××××××××××××××××××××××××××

    AfxBeginThread和CreateThread具体区别

    具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过程中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁的因素,用起来比较繁琐一些,初学的人在用到的时候可能会产生不可预料的错误,建议多使用AfxBeginThread,是编译器对原来的CreateThread函数的封装,用与MFC编程(当然,只要修改了项目属性,console和win32项目都能调用)而_beginthread是C的运行库函数。

    在使用AfxBeginThread时,线程函数的定义为:

    两个的实质都是一样的,不过AfxBeginThread返回一个CWinThread的指针,就是说他会new一个CWinThread对象,而且这个对象是自动删除的(在线程运行结束时),给我们带来的不便就是无法获得它的状态,因为随时都有可能这个指针指向的是一个已经无效的内存区域,所以使用时(如果需要了解它的运行状况的话)首先CREATE_SUSPENDED让他挂起,然后m_bAutoDelete=FALSE,接着才ResumeThread,最后不要了delete那个指针。

    CreatThread就方便多了,它返回的是一个句柄,如果你不使用CloseHandle的话就可以通过他安全的了解线程状态,最后不要的时候CloseHandle,Windows才会释放资源,所以我一般使用CreatThread,方便。

    如果用MFC编程,不要用CreateThread,如果只是使用Runtime Library,用_BegingThread,总之,不要轻易使用CreateThread。这是因为在MFC和RTL中的函数有可能会用到些它们所封装的公用变量,也就是说AfxBeginThread和_BeginThread都有自己的启动代码是CreateThread所没有的。

    在用CreateThread所创建的线程中使用MFC的类和RTL函数就有可能出现问题。如果你是用汇编编写win32程序并且在线程函数中也不调用MFC和RTL的函数,那用CreateThread就没问题,或者你虽然是用C写线程函数,但你很小心没调用RTL函数也不会有问题。

    CreateThread是由操作系统提供的接口,而AfxBeginThread和_BeginThread则是编译器对它的封装。

      在可能的情况下,不要调用_beginthread,而应该调用_beginthreadex。以及对应的_endthreadex。这都是C++运行期函数。但是使用_beginthread,无法创建带有安全属性的新线程,无法创建暂停的线程,也无法获得线程ID,_endthread的情况类似,它不带参数,

      这意味这线程的退出代码必须硬编码为0。这两个函数在_beginthreadex和_endthreadex中进行调用。CreateThread不要进行直接调用。

     

    
    
  • 相关阅读:
    使用CustomValidate自定义验证控件
    C#中金额的大小写转换
    Andriod出错之Unable to build: the file dx.jar was not loaded from the SDK folder!
    VC 编写的打字练习
    机房工作笔记Ping只有单向通
    web服务协同学习笔记(1)
    Dll 学习3 将MDI子窗口封装在DLL中
    机房工作学习文件共享
    Andriod出错之Failed to find an AVD compatible with target 'Android 2.2'
    Andriod出错之wrapper was not properly loaded first
  • 原文地址:https://www.cnblogs.com/wenluderen/p/4246137.html
Copyright © 2020-2023  润新知