线程创建方式

一、Linux下创建线程

C++:
pthread Linux 使用 pthread 库

二、windows 下创建线程

window下共有四种创建线程方法,CreateThread方法为Win API方法,该方法在多线程下用到C Runtime库时会出问题,为解决此问题,产生_beginthread(_beginthreadex)方法;涉及MFC的函数和数据的用AfxBeginThread。各方法介绍如下:

非MFC:
1.CreateThread
2._beginthread(_beginthreadex)
3.二者区别

MFC:
4.AfxBeginThread

2.1 CreateThread:

CreateThread是Windows的API函数,提供操作系统级别的创建线程的操作。_beginthread(及_beginthreadex)与AfxBeginThread的底层实现都调用了CreateThread函数。
CreateThread函数没有考虑到下面二点:
(1)C Runtime中需要对多线程进行记录和初始化,以保证C函数库工作正常(典型的例子就是strtok函数)
(2)MFC也需要知道新线程的创建,也需要做一些初始化工作。
所以,在不调用MFC和CRT的函数时,可以用CreateThread创建线程,其它情况不要使用。

2.2 _beginthread和_beginthreadex

实现文件分别是thread.c和threadex.c
实现方法:是MS对C Runtime库的扩展SDK函数,首先对C Runtime库做了一些初始化的工作,以保证C Runtime库工作正常。然后,调用CreateThread真正创建线程。
若要使多线程C和C++程序能够正确地运行,必须创建一个数据结构,并将它与使用C/C++运行期库函数的每个线程关联起来。当你调用C/C++运行期库时,这些函数必须知道查看调用线程的数据块,这样就不会对别的线程产生不良影响。
1.每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。
2.传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也保存在该数据块中。(指向tiddata结构的指针会作为一个TLS保存起来)
3._beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的唯一方法
4.当调用CreatetThread时,它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行新线程。还有,传递给线程函数的参数是tiddata结构而不是pvParam的地址。
5.如果一切顺利,就会像CreateThread那样返回线程句柄。如果任何操作失败了,便返回 NULL。

总结:如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()

2.3 Windows下使用CreateThread()和_beginthreadex()的区别

根据《Win32多线程程序设计》中的介绍,当创建的子程序中包含某些C runtime 函数时,不应该使用CreateThread()。
如果主线程以外的任意新建的线程中包含以下操作,则应该使用多线程版本的C runtime library,并使用_beginthreadex()和_endthreadex():

在C程序中使用malloc()和free(),或者在C++程序中使用new()和delete();
调用stdio.h或io.h中声明的任何函数,包括fopen()、open()、getchar()、write()、printf()等等。所有这些函数都用到共享的数据结构以及errno。对于格式化操作,如果不想使用C runtime library的函数,你可以使用wsprintf()来替代printf()(wsprintf()是Win内核自己实现的,不依赖于C runtime library,其与printf()大同小异,唯一区别是在浮点数的处理上不同);
使用浮点变量或者浮点运算函数;
调用任何一个使用了静态缓冲区的runtime函数,如asctime()、strtok或rand()。
如果新建的线程里面没有以上列出来的事项,则可以用单线程版本的runtime library和CreateThread()。
此外,如果要在MFC程序中产生一个线程,而该线程将调用MFC函数或使用MFC的任何数据,那么必须使用AfxBeginThread()或CWinThread::CreateThread()来产生线程。
参考文章:https://blog.csdn.net/weixin_43376501/article/details/108704218

2.4 AfxBeginThread

MFC中线程创建的函数,首先创建了相应的CWinThread对象,然后调用CWinThread::CreateThread,在CWinThread::CreateThread中完成了对线程对象的初始化工作,然后调用_beginthreadex创建线程。注意不要在一个MFC程序中使用_beginthreadex()或CreateThread()。
两个版本:1.用户界面线程;2.工作现象
使用方法:https://docs.microsoft.com/en-us/previous-versions/s3w9x78e(v=vs.140)?redirectedfrom=MSDN

三、C++ 创建线程

C++ 11发布之前,C++并没有对多线程编程的专门支持,C++ 11通过标准库引入 std::thread 实现对多线程的支持。
1.std::thread
参考文章:https://blog.csdn.net/u011808673/article/details/80811998

你可能感兴趣的:(C++,知识点,多线程)