《2022年多线程编程 .pdf》由会员分享,可在线阅读,更多相关《2022年多线程编程 .pdf(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、win32 多线程编程要点2007/06/24 01:02 线程是进程的一条执行路径,它包含独立的堆栈和CPU 寄存器状态,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等。一个进程内 的所有线程使用同一个地址空间,而这些线程的执行由系统调度程序控制,调度程序决定哪个线程可执行以及什么时候执行线程。线程有优先级别,优先权较低的线程必须等到优先权较高的线程执行完后再执行。在多处理器的机器上,调度程序可将多个线程放到不同的处理器上去运行,这样可使处理器任务平衡,并提高系统的运行效率。Windows是一种多任务的操作系统,在 Windows的一个进程内包含一个或多个线程。32
2、位 Windows环境下的 Win32 API 提供了多线程应用程序开发所需要的接口函数,而利用中提供的标准库也可以开发多线程应用程序,相应的类库封装了多线程编程的类,用户在开发时可根据应用程序的需要和特点选择相应的工具。为了使大家能全面地了解Windows多线程编程技术,本文将重点介绍 Win32 API 和 MFC 两种方式下如何编制多线程程序。多线程编程在 Win32方式下和 MFC 类库支持下的原理是一致的,进程的主线程在任何需 要的时候都可以创建新的线程。当线程执行完后,自动终止线程;当进程结束后,所有的线程都终止。所有活动的线程共享进程的资源,因此,在编程时需要考虑在多个线程访问同
3、一资源时产生冲突的问题。当一个线程正在访问某进程对象,而另一个线程要改变该对象,就可能会产生错误的结果,编程时要解决这个冲突。Win32 API 下的多线程编程Win32 API 是 Windows操作系统内核与应用程序之间的界面,它将内核提供的功能进行函数包装,应用程序通过调用相关函数而获得相应的系统功能。为了向应用 程序提供多线程功能,Win32 API 函数集中提供了一些处理多线程程序的函数集。直接用 Win32 API 进行程序设计具有很多优点:基于 Win32的应用程序执行代码小,运行效率高,但是它要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源。用 Win32 API
4、直接编写程序要求程序员对Windows系统内核有一定的了解,会占用程序员很多时间对系统资源进行管理,因而程序员的工作效率降低。1.用 Win32函数创建和终止线程Win32函数库中提供了操作多线程的函数,包括创建线程、终止线程、建立互斥区等。在应用程序的主线程或者其他活动线程中创建新的线程的函数如下:HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreat
5、ionFlags,LPDWORD lpThreadId);如果创建成功则返回线程的句柄,否则返回NULL。创建了新的线程后,该线程名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 13 页 -就开始启动执行了。但如果在 dwCreationFlags 中使用了 CREATE_SUSPENDED特性,那么线程并不马上执行,而是先挂起,等到调用ResumeThread后才开始启动线程,在这个过程中可以调用下面这个函数来设置线程的优先权:BOOL SetThreadPriority(HANDLE hThread,int nPriority);当调用线程的函数返回后,线程自动终止。如果需要
6、在线程的执行过程中终止则可调用函数:VOID ExitThread(DWORD dwExitCode);如果在线程的外面终止线程,则可调用下面的函数:BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);但应注意:该函数可能会引起系统不稳定,而且线程所占用的资源也不释放。因此,一般情况下,建议不要使用该函数。如果要终止的线程是进程内的最后一个线程,则线程被终止后相应的进程也应终止。2.线程的同步在 线程体内,如果该线程完全独立,与其他线程没有数据存取等资源操作上的冲突,则可按照通常单线程的方法进行编程。但是,在多线程处理时情况常常不是这样,
7、线程之间经常要同时访问一些资源。由于对共享资源进行访问引起冲突是不可避免的,为了解决这种线程同步问题,Win32 API 提供了多种同步控制对象来帮助程序员解决共享资源访问冲突。在介绍这些同步对象之前先介绍一下等待函数,因为所有控制对象的访问控制都要用到这个函数。Win32 API 提供了一组能使线程阻塞其自身执行的等待函数。这些函数在其参数中的一个或多个同步对象产生了信号,或者超过规定的等待时间才会返回。在等待函数未返回时,线程处于等待状态,此时线程只消耗很少的CPU 时间。使用等待函数既可以保证线程的同步,又可以提高程序的运行效率。最常用的等待函数是:DWORD WaitForSingle
8、Object(HANDLE hHandle,DWORD dwMilliseconds);而函数 WaitForMultipleObject可以用来同时监测多个同步对象,该函数的声明为:DWORD WaitForMultipleObject(DWORD nCount,CONST HANDLE*lpHandles,BOOL bWaitAll,DWORD dwMilliseconds);名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 13 页 -(1)互斥体对象Mutex 对象的状态在它不被任何线程拥有时才有信号,而当它被拥有时则无信号。Mutex 对象很适合用来协调多个线程对共享资源
9、的互斥访问。可按下列步骤使用该对象:首先,建立互斥体对象,得到句柄:HANDLE CreateMutex();然后,在线程可能产生冲突的区域前(即访问共享资源之前)调用WaitForSingleObject,将句柄传给函数,请求占用互斥对象:dwWaitResult=WaitForSingleObject(hMutex,5000L);共享资源访问结束,释放对互斥体对象的占用:ReleaseMutex(hMutex);互斥体对象在同一时刻只能被一个线程占用,当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才能成功。(2)信号对象信 号对象允许同时对多个线程共享资源进行
10、访问,在创建对象时指定最大可同时访问的线程数。当一个线程申请访问成功后,信号对象中的计数器减一,调用ReleaseSemaphore函数后,信号对象中的计数器加一。其中,计数器值大于或等于,但小于或等于创建时指定的最大值。如果一个应用在创建一个信号对象时,将其计数器的初始值设为,就阻塞了其他线程,保护了资源。等初始化完成后,调用 ReleaseSemaphore函数将其计数器增加至最大值,则可进行正常的存取访问。可按下列步骤使用该对象:首先,创建信号对象:HANDLE CreateSemaphore();或者打开一个信号对象:HANDLE OpenSemaphore();然后,在线程访问共享资
11、源之前调用WaitForSingleObject。共享资源访问完成后,应释放对信号对象的占用:ReleaseSemaphore();名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 13 页 -(3)事件对象事件对象(Event)是最简单的同步对象,它包括有信号和无信号两种状态。在线程访问某一资源之前,需要等待某一事件的发生,这时用事件对象最合适。例如:只有在通信端口缓冲区收到数据后,监视线程才被激活。事 件对象是用 CreateEvent 函数建立的。该函数可以指定事件对象的类和事件的初始状态。如果是手工重置事件,那么它总是保持有信号状态,直到用ResetEvent 函数重置成无
12、信号的事件。如果是自动重置事件,那么它的状态在单个等待线程释放后会自动变为无信号的。用 SetEvent 可以把事件对象设置成有信号状态。在建立事件时,可以为对象命名,这样其他进程中的线程可以用OpenEvent函数打开指定名字的事件对象句柄。(4)排斥区对象在排斥区中异步执行时,它只能在同一进程的线程之间共享资源处理。虽然此时上面介绍的几种方法均可使用,但是,使用排斥区的方法则使同步管理的效率更高。使用时先定义一个CRITICAL_SECTION 结构的排斥区对象,在进程使用之前调用如下函数对对象进行初始化:VOID InitializeCriticalSection(LPCRITICAL_
13、SECTION);当一个线程使用排斥区时,调用函数:EnterCriticalSection或者TryEnterCriticalSection;当要求占用、退出排斥区时,调用函数LeaveCriticalSection,释放对排斥区对象的占用,供其他线程使用。基于 MFC 的多线程编程MFC 是微软的 VC开发集成环境中提供给程序员的基础函数库,它用类库的方式将 Win32 API 进行封装,以类的方式提供给开发者。由于其快速、简捷、功能强大等特点深受广大开发者喜爱。因此,建议使用MFC 类库进行应用程序的开发。在 VC+附带的 MFC 类库中,提供了对多线程编程的支持,基本原理与基于 Win
14、32 API 的设计一致,但由于MFC 对同步对象做了封装,因此实现起来更加方便,避免了对象句柄管理上的烦琐工作。在 MFC 中,线程分为两种:工作线程和用户接口线程。工作线程与前面所述的线程一致,用户接口线程是一种能够接收用户的输入、处理事件和消息的线程。1.工作线程名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 13 页 -工作线程编程较为简单,设计思路与前面所讲的基本一致:一个基本函数代表了一个线程,创建并启动线程后,线程进入运行状态;如果线程用到共享资源,则需要进行资源同步处理。这种方式创建线程并启动线程时可调用函数:CWinThread*AfxBeginThread(A
15、FX_THREADPROC pfnThreadProc,LPVOID pParam,int nPriority=THREAD_PRIORITY_NORMAL,UINT nStackSize=0,DWORD dwCreateFlags=0,LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);参数pfnThreadProc 是线程执行体函数,函数原形为:UINT ThreadFunction(LPVOID pParam)。参数 pParam是传递给执行函数的参数;参数 nPriority是线程执行权限,可选值:THREAD_PRIORITY_NORMAL、THR
16、EAD_PRIORITY_LOWEST、THREAD_PRIORITY_HIGHEST、THREAD_PRIORITY_IDLE。参数 dwCreateFlags 是线程创建时的标志,可取值CREATE_SUSPENDED,表示线程创建后处于挂起状态,调用ResumeThread函数后线程继续运行,或者取值“0”表示线程创建后处于运行状态。返 回值是 CWinThread类对象指针,它的成员变量m_hThread为线程句柄,在Win32 API 方式下对线程操作的函数参数都要求提供线程的句柄,所以当线程创建后可以使用所有 Win32 API 函数对 pWinThread-m_Thread线程进
17、行相关操作。注意:如果在一个类对象中创建和启动线程时,应将线程函数定义成类外的全局函数。2.用户接口线程基 于 MFC 的应用程序有一个应用对象,它是CWinApp派生类的对象,该对象代表了应用进程的主线程。当线程执行完并退出线程时,由于进程中没有其他线程存在,进程自动结束。类CinApp 从 CinThread 派生出来,CinThread 是用户接口线程的基本类。我们在编写用户接口线程时,需要从 CinThread 派生我们自己的线程类,ClassWizard 可以帮助我们完成这个工作。先用 ClassWizard 派生一个新的类,设置基类为CwinThread。注意:类的DECLARE_
18、DYNCREATE和 IMPLEMENT_DYNCREATE宏是必需的,因为创建线程时需要动态创建类的对象。根据需要可将初始化和结束代码分别放在类的InitInstance和 ExitInstance函数中。如果需要创建窗口,则可在InitInstance函数中完成。然后创建线程并启动线程。可以用两种方法来创建用户接口线程,MFC 提供了两个版本的 AfxBeginThread函数,其中一个用于创建用户接口线程。第二种方法分为两步进行:首先,调用线程类的构造函数创建一个线程对象;其次,调用 CWinThread:CreateThread函数来创建该线程。线程建立并启动后,在线程函数执行过程中一
19、直有效。如果是线程对象,则在对象名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 13 页 -删除之 前,先结束线程。CWinThread已经为我们完成了线程结束的工作。3.线程同步前面我们介绍了 Win32 API 提供的几种有关线程同步的对象,在 MFC 类库中对这几个对象进行了类封装,它们有一个共同的基类CSyncObject,它们的对应关系为:Semaphore 对应 CSemaphore、Mutex 对应 CMutex、Event 对应 CEvent、CriticalSection对应 CCriticalSection。另外,MFC 对两个等待函数也进行了封装,即 CSi
20、ngleLock 和 CMultiLock。因四个对象用法相似,在 这里就以 CMutex为例进行说明:创建一个 CMutex对象:CMutex mutex(FALSE,NULL,NULL);或 CMutex mutex;当各线程要访问共享资源时使用下面代码:CSingleLock sl(&mutex);sl.Lock();if(sl.IsLocked()/对共享资源进行操作.sl.Unlock();结束语如果用户的应用程序需要多个任务同时进行相应的处理,则使用多线程是较理想的选择。这里,提醒大家注意的是在多线程编程时要特别小心处理资源共享问题以及多线程调试问题一、引言-在 Windows 的
21、一个进程内,包含一个或多个线程。线程是指进程的一条执行路径,它包含独立的堆栈和 CPU 寄存器状态,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等等。一个进程内的所有线程使用同一个32 位地址空间,而这些线程的执行由系统调度程序控制,调度程序决定哪个线程可执行以及什么时候执行线程。线程有优先级别,优先权较低的线程必须等到优先权较高的线程执行完任务后再执行。在多处理器的机器上,调度程序可将多个线程放到不同的处理器上去运行,这样就可使处理器的任务平衡,也提高了系统的运行效率。名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 13 页 -32 位 Windows
22、环境下的 Win32 API 提供了多线程应用程序开发所需要的接口函数;MFC 类库也封装了多线程编程的类,即我们既可以用Windows 提供的 API 编写多线程程序,也可以用MFC 开发多线程应用程序,因而用户在开发时可根据应用程序的需要和特点选择相应的工具。如果用户的应用程序需要有多个任务同时进行相应的处理,则使用多线程是较理想的选择。二、基于 Visual C+的多线程编程-多线程的编程在Win32 方式下和 MFC 类库支持下的原理是一致的,进程的主线程在任何需要的时候都可以创建新的线程。当线程执行完任务后,自动中止线程;当进程结束后,所有的线程都中止。所有活动的线程共享进程的资源。
23、因此,在编程时需要考虑在多个线程访问同一资源时产生冲突的问题:当一个线程正在访问一个进程对象时,另一个线程要改变该对象,这时可能会产生错误的结果。所以,程序员编程时要解决这种冲突。下面介绍一下在Win32 基础上进行多线程编程的过程。-1.用 Win32 函数创建和中止线程-Win32 函数库中提供了多线程控制的操作函数,包括创建线程、中止线程、建立互斥区等。首先,在应用程序的主线程或者其它活动线程的适当地方创建新的线程。创建线程的函数如下:HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,/指定了线程的安全属性,在Wi
24、ndows 95 中被忽略DWORD dwStackSize,/指定了线程的堆栈深度LPTHREAD_START_ROUTINE lpStartAddress,/线程函数 LPVOID lpParameter,/指定了线程执行时传送给线程的32 位参数 DWORD dwCreationFlags,/指定了线程创建的特性LPDWORD lpThreadId/指向一个 DWORD 变量,可返回线程ID 值);如果创建成功则返回线程的句柄,否则返回NULL。创建了新的线程后,则该线程就开始启动执行了。如果在 dwCreationFlags中用了 CREATE_SUSPENDED特性,那么线程并不马上
25、执行,而是先名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 13 页 -挂起,等到调用 ResumeThread后才开始启动线程,在这个过程中可以调用函数:BOOL SetThreadPriority(HANDLE hThread,int nPriority);来设置线程的优先权。当线程的函数返回后,线程自动中止。如果在线程的执行过程中中止的话,则可调用函数:VOID ExitThread(DWORD dwExitCode);如果在线程的外面中止线程的话,则可调用下面的函数:BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode)
26、;但应注意:该函数可能会引起系统不稳定,而且线程所占用的资源也不释放。因此,一般情况下,建议不要使用该函数。如果要中止的线程是进程内的最后一个线程,则在线程被中止后相应的进程也应中止。2.用 Win32 函数控制线程对共享资源的访问-在线程体内,如果该线程完全独立,与其它的线程没有数据存取等资源操作上的冲突,则可按照通常单线程的方法进行编程。但是,在多线程处理时情况常常不是这样,线程之间经常要同时访问一些资源。例如,一个线程负责公式计算,另一个线程负责结果的显示,两个线程都要访问同一个结果变量。这时如果不进行冲突控制的话,则很可能显示的是不正确的结果。对共享资源进行访问引起冲突是不可避免的,但
27、我们可用以下办法来进行操作控制:(1)通过设置线程的互斥体对象,在可能冲突的地方进行同步控制。-首先,建立互斥体对象,得到句柄:HANDLE CreateMutex();然后,在线程可能冲突区域的开始(即访问共享资源之前),调用 WaitForSingleObject将句柄传给函数,请求占用互斥体对象:dwWaitResult=WaitForSingleObject(hMutex,5000L);共享资源访问完后,释放对互斥体对象的占用:ReleaseMutex(hMutex);互斥体对象在同一时刻只能被一个线程占用。当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才
28、能成功。名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 13 页 -(2)设置信号:在操作共享资源前,打开信号;完成操作后,关闭信号。这类似于互斥体对象的处理。-首先,创建信号对象:HANDLE CreateSemaphore();或者打开一个信号对象:HANDLE OpenSemaphore();然后,在线程的访问共享资源之前调用WaitForSingleObject。共享资源访问完后,释放对信号对象的占用:ReleaseSemaphore();信号对象允许同时对多个线程共享资源的访问,在创建对象时指定最大可同时访问的线程数。当一个线程申请访问成功后,信号对象中的计数器减一;调
29、用ReleaseSemaphore函数后,信号对象中的计数器加一。其中,计数器值大于等于0,小于等于创建时指定的最大值。利用信号对象,我们不仅可以控制共享资源的访问,还可以在应用的初始化时候使用。假定一个应用在创建一个信号对象时,将其计数器的初始值设为0,这样就阻塞了其它线程,保护了资源。待初始化完成后,调用ReleaseSemaphore函数将其计数器增加至最大值,进行正常的存取访问。(3)利用事件对象的状态,进行线程对共享资源的访问。-用 ResetEvent函数设置事件对象状态为不允许线程通过;用 SetEvent 函数设置事件对象状态为可以允许线程通过。事件分为手工释放和自动释放。如果
30、是手工释放,则按照上述两函数处理事件的状态;如果是自动释放,则在一个线程结束后,自动清除事件状态,允许其它线程通过。(4)设置排斥区。-在排斥区中异步执行时,它只能在同一进程的线程之间共享资源处理。虽然此时上面介绍的三种方法均可使用,但是,使用排斥区的方法则使同步管理的效率更高;先定义一个 CRITICAL_SECTION结构的排斥区对象,在进程使用之前先对对象进行初始化,调用如下函数:VOID InitializeCriticalSection(LPCRITICAL_SECTION);名师资料总结-精品资料欢迎下载-名师精心整理-第 9 页,共 13 页 -当一个线程使用排斥区时,调用函数:
31、EnterCriticalSection或者 TryEnterCriticalSection 当要求占用、退出排斥区时,调用函数:LeaveCriticalSection 释放对排斥区对象的占用,供其它线程使用。互斥体对象、信号对象和事件对象也可以用于进程间的线程同步操作。在用 Win32 函数创建了对象时,我们可以指定对象的名字,还可以设置同步对象在子进程的继承性。创建返回的是HANDLE 句柄,我们可以用函数DuplicateHandle来复制对象句柄,这样每个进程都可以拥有同一对象的句柄,实现进程之间的线程同步操作。另外,在同一进程内,我们可以用OpenMutex、OpenSemapho
32、re和 OpenEvent来获得指定名字的同步对象的句柄。排斥区异步执行的线程同步方法只能用于同一进程的线程之间共享资源处理,但是这种方法的使用效率较高,而且编程也相对简单一些。未完,待继.所属分类:C/C+工具平台和程序库-在看候捷的Win32 多线程程序设计,有几个小问题1、win32 多线程程序设计和c 多线程有关系吗?有什么区别?底什么是win32 多线程编程?CreateThread 和_beginthread有什么区别?2、到底什么是核心对象?好像候捷的书上说的有点矛盾啊,他说createThread传回来的 handle 被称为核心对象,可看到后来他又说核心对象包括进程、线程、文
33、件等。核心对象到底有什么作用他书上有段话:_beginthreadex的参数和 CreatThread 的参数其实完全相同(这句就不明白,完全相同起不同的名字干什么?)不过它把WIN32 的数据类型净化了,所谓净化,就是用标准的C 数据类型代替windows 自定义的数据类型,参数类型被净化,主要是要使这个函数能移植到其他操作系统,理论上净化了win32 数据类型之后,_beginthreadex就可以实现于其他平台,因为完全不需要windows.h,但不幸的是还要调用 closehandle,所以还要含如windows.h(其他平台下不能调用closehandle?还是其他平台不支持多线程编
34、程?)名师资料总结-精品资料欢迎下载-名师精心整理-第 10 页,共 13 页 -可能有的问题比较菜,不过我真的不太懂,希望有人能帮我解答一下,多谢了-为什么我发的帖子在列表里看不到啊?有人能看到吗?-参数用不同的名字只是为了便于理解.-核心对象就像针对操作系统的全局变量一样,比如你建立的没一个进程,都只有一个系统唯一的进程id 号,根据这个id 号,也就是所谓的handle,你可以调函数查询倒这个进程在系统里面的情况,比如使用的内存,虚拟内存比列等等。多线程的实现实际上只是屏蔽了系统的多线程实现而已,标准c 的线程和windows库函数的线程底层的实现原理应该是一样的你看怎么用方便,另外程序
35、如果需要移植等等最好用标c 的,因为比如在别的支持标c 的系统下面,他同样屏蔽了底层的实现,你可以直接使用-核心对象的这些数据,比如空间的占用等等,是规系统直接管理的,所以你只能构通过调函数去访问,而不能得到实际的地址去修改,也许是为了安全的考虑吧。-Win32 多线程这本我也看过,写的不错,但是很多细节还是没有涉及到。推荐楼主看看Windows 核心编程有比较详尽的解释。-真正的系统API 接口是 CreateThread;_beginthread是对 CreateThread 的封装,也就是说 _beginthread最终也是需要调用CreateThread 来实现多线程的。名师资料总结-
36、精品资料欢迎下载-名师精心整理-第 11 页,共 13 页 -也许 MS 封装了 _beginthread的本意是想让 _beginthread称为跨平台的多线程标准函数。但是不幸是这个目标并没有实现。现在倒是有一套可移植的跨平台多线程函数库pthread,它在多个unix/linux系统上得到实现。-真正的系统API 接口是 CreateThread;_beginthread是对 CreateThread 的封装,也就是说 _beginthread最终也是需要调用CreateThread 来实现多线程的。-_beginthreadex调用 CreatThread?我现在的理解就是CreatT
37、hread 就是 windows 平台下的,如果 _beginthreadex是通过调用 createthread来实现的,那么怎么跨平台使用啊?即使别的平台支持_beginthreadex,但是它不支持createThread还不是一样等于_beginthreadex不能跨平台?-Windows 核心编程里有讲到,_beginThread会对 c/c+的一些堆栈还有一些参数做一些处理,参见第6 章-.现在,假设在调用s y s t e m函数之后和调用i f 语句之前,执行上面代码的线程中断运行,同时假设,该线程中断运行是为了让同一进程中的第二个线程开始执行,而这个新线程将执行另一个负责设置
38、全局变量e r r n o的 C 运行期函数。当 C P U 在晚些时候重新分配给第一个线程时,e r r n o的值将不再能够反映调用上面代码中的s y s t e m函数时的错误代码。为了解决这个问题,每个线程都需要它自己的e r r n o变量。此外,必须有一种机制,使得线程能够引用它自己的e r r n o变量,但是又不触及另一个线程的e r r n o变量。这是标准 C/C+运行期库原先并不是设计用于多线程应用程序的唯一一个例子。在多线程环境中存在问题的C/C+运行期库变量和函数包括e r r n o、_ d o s e r r n o、s t r t o k、_ w c s t o
39、 k、s t r e r r o r、_ s t r e r r o r、t m p n a m、t m p f i l e、a s c t i m e、_ w a s c t i m e、g m t i m e、_ e c v t和_ f c v t等。名师资料总结-精品资料欢迎下载-名师精心整理-第 12 页,共 13 页 -若要使多线程C 和 C+程序能够正确地运行,必须创建一个数据结构,并将它与使用 C/C+运行期库函数的每个线程关联起来。当你调用C/C+运行期库时,这些函数必须知道查看调用线程的数据块,这样就不会对别的线程产生不良影响。那么系统是否知道在创建新线程时分配该数据块呢?回
40、答是它不知道。系统根本不知道你得到的应用程序是用C/C+编写的,也不知道你调用函数的线程本身是不安全的。问题在于你必须正确地进行所有的操作。若要创建一个新线程,绝对不要调用操作系统的C r e a t e T h r e a d函数,必须调用C/C+运行期库函数_ b e g i n t h r e a d e x:unsigned long _beginthreadex(void*security,unsigned stack_size,unsigned*start_address)(void*),void*arglist,unsigned initflag,unsigned*thrdaddr);.-还有一本 C面向对象多线程编程,比 win32 多线程要好,很多概念都有详细的解释,网上有电子版-win32 多线程就是指的windows 平台下的多线程编程?我现在就是这么理解的,不知道对不对,其他非 windows 平台下是如何实现多线程的?有人可以解答一下吗?名师资料总结-精品资料欢迎下载-名师精心整理-第 13 页,共 13 页 -