• (转)线程相关的东东


    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不要进行直接调用。

     

    
    
  • 相关阅读:
    关于C#中Environment.OSVersion判断操作系统及Win10上的问题
    C#各种数组直接的数据复制/转换
    移位操作<<和>>,是逻辑数字上的移动(和大端小端无关)
    log4net学习笔记
    链接错误——无法解析的外部符号 ConvertStringToBST
    当Thread.Sleep的暂停时间参数设置过小时,精度很差的解决方法
    Python发送邮件
    Python使用HTMLTestRunner运行所有用例并产生报告
    pandas学习笔记
    Python requests模块做接口测试
  • 原文地址:https://www.cnblogs.com/wenluderen/p/4246137.html
Copyright © 2020-2023  润新知