CreateThread与_beginthread的区别是?注意事项是?

解决方案 »

  1.   

    CreateThread系统API;
    _beginthread,c/C++实时库函数,其中调用CreateThread;
    _beginthread可跨平台,建议使用_beginthread
      

  2.   

    摘自《windows 核心编程》:CreateThread函数是用来创建线程的Windows函数。不过,如果你正在编写C/C++代码,决不应该调用CreateThread。相反,应该使用Visual C++运行期库函数_beginthreadex。如果不使用Microsoft的Visual C++编译器,你的编译器供应商有它自己的CreateThred替代函数。若要使多线程C和C++程序能够正确地运行,必须创建一个数据结构,并将它与使用C/C++运行期库函数的每个线程关联起来。当你调用C/C++运行期库时,这些函数必须知道查看调用线程的数据块,这样就不会对别的线程产生不良影响。1.每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。
    2.传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也
    保存在该数据块中。
    3._beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的
    唯一方法。
    4.当调用CreatetThread时,它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行
    新线程。还有,传递给线程函数的参数是tiddata结构而不是pvParam的地址
    5.如果一切顺利,就会像CreateThread那样返回线程句柄。如果任何操作失败了,便返回
    NULL_beginthreadex和_beginthread函数的区别。_beginthread函数的参数比较少,因此比特性全面的_beginthreadex函数受到更大的限制。
    例如,如果使用_beginthread,就无法创建带有安全属性的新线程,无法创建暂停的线程,也
    无法获得线程的ID值。
      

  3.   

    总的说来,_beginthreadex就是先做了很多其他工作,来保证在多线程条件下,C++运行期库能够正常运作,然后在调用CreatetThread,在线程退出后,,_beginthreadex还保证了对C++运行期库的一些清理工作
      

  4.   

    LS是说在多数情况下要优先使用_beginthread??欢迎继续讨论
      

  5.   

    如果你的程序中不使用C/C++运行期库,那用CreatetThread没什么问题。但是如果你的程序中使用了C/C++运行期库,那就必须用_beginthread/_beginthreadex(这两个的区别就是参数不一样,你能得到的信息不一样,对线程控制的权利不一样)
      

  6.   

    使用CreateThread会有哪些后果,如何选用?
      

  7.   

    内存泄露、有些C/C++函数在不同的线程下会得到不可预知的结果。
    早期的C/C++开发小组没有考虑到多线程情况,使用了全局变量,在函数内部使用了静态变量,这些变量就会有“线程同步”的问题
      

  8.   

    _beginthreadex的源代码:uintptr_t __cdecl _beginthreadex (
            void *security,
            unsigned stacksize,
            unsigned (__stdcall * initialcode) (void *),
            void * argument,
            unsigned createflag,
            unsigned *thrdaddr
            )
    {
            _ptiddata ptd;                  /* pointer to per-thread data */
            uintptr_t thdl;                 /* thread handle */
            unsigned long errcode = 0L;     /* Return from GetLastError() */
            unsigned dummyid;               /* dummy returned thread ID */        if ( initialcode == NULL ) {
                errno = EINVAL;
                return( (uintptr_t)0 );
            }        /*
             * Allocate and initialize a per-thread data structure for the to-
             * be-created thread.
             */
            if ( (ptd = _calloc_crt(1, sizeof(struct _tiddata))) == NULL )
                    goto error_return;        /*
             * Initialize the per-thread data
             */        _initptd(ptd);        ptd->_initaddr = (void *) initialcode;
            ptd->_initarg = argument;
            ptd->_thandle = (uintptr_t)(-1);        /*
             * Make sure non-NULL thrdaddr is passed to CreateThread
             */
            if ( thrdaddr == NULL )
                    thrdaddr = &dummyid;        /*
             * Create the new thread using the parameters supplied by the caller.
             */
            if ( (thdl = (uintptr_t)
                  CreateThread( security,
                                stacksize,
                                _threadstartex,
                                (LPVOID)ptd,
                                createflag,
                                thrdaddr))
                 == (uintptr_t)0 )
            {
                    errcode = GetLastError();
                    goto error_return;
            }        /*
             * Good return
             */
            return(thdl);        /*
             * Error return
             */
    error_return:
            /*
             * Either ptd is NULL, or it points to the no-longer-necessary block
             * calloc-ed for the _tiddata struct which should now be freed up.
             */
            _free_crt(ptd);        /*
             * Map the error, if necessary.
             *
             * Note: this routine returns 0 for failure, just like the Win32
             * API CreateThread, but _beginthread() returns -1 for failure.
             */
            if ( errcode != 0L )
                    _dosmaperr(errcode);        return( (uintptr_t)0 );
    }
      

  9.   

    LS是说在多数情况下要优先使用_beginthread??