• _beginthreadex()和CreateThread()的区别


    在本例子中我们使用——beginThreadex这个函数,它和createThread的区别是:

    为了方便管理,我么在使用该函数的时候可以把它的线程函数作为类成员,这也就需要在类中把该函数变成静态函数

    //test.h:
    static unsigned __stdcall ThreadProc( void * );

    1)如果你正在编写C/C++代码,决不应该调用CreateThread。相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex。如果不使用Microsoft的VisualC++编译器,你的编译器供应商有它自己的CreateThred替代函数。不管这个替代函数是什么,你都必须使用。
    2)因为_beginthreadex和_endthreadex是CRT线程函数,所以必须注意编译选项runtimelibaray的选择,使用MT或MTD。

    3) _beginthreadex函数的参数列表与CreateThread函数的参数列表是相同的,但是参数名和类型并不完全相同。这是因为Microsoft的C/C++运行期库的开发小组认为,C/C++运行期函数不应该对Windows数据类型有任何依赖。_beginthreadex函数也像CreateThread那样,返回新创建的线程的句柄。

    4)下面是关于_beginthreadex的一些要点:

    总得来说createthread是windowsAPI函数,而_beginthreadex是c++函数,这个函数会创建一个内存块,然后内部调用CreateThread

    而_endthreadex做了两件事,释放内存和调用ExitThread()(只调用此函数不会自己释放内存)

    •每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。(tiddata结构位于Mtdll.h文件中的VisualC++源代码中)。

    •传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也保存在该数据块中。

    •_beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的唯一方法。

    •当调用CreatetThread时,它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行新线程。还有,传递给线程函数的参数是tiddata结构而不是pvParam的地址。

    •如果一切顺利,就会像CreateThread那样返回线程句柄。如果任何操作失败了,便返回NULL。

    5) _endthreadex的一些要点:

    •C运行期库的_getptd函数内部调用操作系统的TlsGetValue函数,该函数负责检索调用线程的tiddata内存块的地址。

    •然后该数据块被释放,而操作系统的ExitThread函数被调用,以便真正撤消该线程。当然,退出代码要正确地设置和传递。

    6) 虽然也提供了简化版的的_beginthread和_endthread,但是可控制性太差,所以一般不使用。

    6)线程handle因为是内核对象,所以需要在最后close handle。

    7)C++主线程的终止,同时也会终止所有主线程创建的子线程,不管子线程有没有执行完毕。

    8)如果某线程挂起,然后有调用WaitForSingleObject等待该线程,就会导致死锁

     来自:https://www.cnblogs.com/itech/archive/2010/06/29/1767311.html

  • 相关阅读:
    mysql-规避重复插入
    redis-string
    redis-map
    跨库修改
    Python-批量插入
    Python-批量修改
    MongoDB操作符
    Cron表达式
    Mycat修改空指针问题
    项目中常用的linux命令
  • 原文地址:https://www.cnblogs.com/curo0119/p/8352977.html
Copyright © 2020-2023  润新知