多线程同步互斥,互斥是指某一资源一段时间内只允许一个访问者进行访问,同步是指在互斥的基础上,多个线程或进程按照一定顺序来运行 。
c++语言本身没有提供多线程机制,windows系统为我们提供了相关的API。
windowsAPI 提供了函数 CreateThread(),其基本过程为:
1.在内核对象中分配一个线程标识/句柄,可供管理,由CreateThread返回
2.把线程退出码置为STILL_ACTIVE,把线程挂起计数置1
3.分配context结构
4.分配两页的物理存储以准备栈,保护页设置为PAGE_READWRITE,第2页设为PAGE_GUARD
5.lpStartAddr和lpvThread值被放在栈顶,使它们成为传送给StartOfThread的参数
6.把context结构的栈指针指向栈顶(第5步)指令指针指向startOfThread函数
函数为
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
第一个参数为线程内核安全属性,默认为NULL,
第二个参数为线程栈的空间大小,传入0表示使用默认大小1MB,而windows也会根据情况来动态延长堆栈大小。
第三个参数为 线程函数地址,使用DWORD WINAPI ThreadProc (LPVOID pParam) ; 来声明一个线程函数。(DWORD为双字即32bit,4字节,LPVOID为void指针,指向函数的参数)
第四个参数为传给线程函数的参数。
第五个函数 指定额外的标志来控制线程的创建,为0表示线程创建后立即调度,为CREATE_SUSPENDED表示线程创建后暂停运行,直到调用RESUMETHREAD(HANDLE );
第六个参数返回线程ID号,若为NULL,则不返回,为指针则将ID赋值个指针指向的地址。
多线程中常用的几个函数:
GetCurrentThreadId() 返回线程ID。
WaitForSingleObject
函数功能:等待函数 – 使线程进入等待状态,直到指定的内核对象被触发。
函数原形:
DWORD WIN API WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
函数说明:
第一个参数为要等待的内核对象。
第二个参数为最长等待的时间,以毫秒为单位,如传入5000就表示5秒,传入0就立即返回,传入INFINITE表示无限等待。
因为线程的句柄在线程运行时是未触发的,线程结束运行,句柄处于触发状态。所以可以用WaitForSingleObject()来等待一个线程结束运行。
函数返回值:
在指定的时间内对象被触发,函数返回WAIT_OBJECT_0。超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT。传入参数有错误将返回WAIT_FAILED。
等待数组iphandles中所有线程句柄执行结束。
DWORD WaitForMultipleObjects(
DWORD nCount,//数组长度
const HANDLE* lpHandles,//数组指针
BOOL bWaitAll,//是否等待全部线程
DWORD dwMilliseconds//最大等待时间
);
不推荐使用CREATETHREAD的原因是c语言中为考虑多线程,如使用全局变量errno,则对于strerror()、strtok()、tmpnam()、gmtime()等函数会线程不安全,所以编译器建议使用这些函数的线程安全的新版本,或者使用线程安全的函数 _beginthreadex()。
_beginthreadex():
这个函数对于标准c库中进行的线程安全的解决办法是对于任意一个线程,配置一块专有的内存区来供c库中的函数使用。
这里发现,其实对于现在的编译器,已经不必使用这个函数了,因为不使用之前几个函数的线程安全型新函数就 给 编译错误,则,这个函数的线程安全的优势就没了,而且对于函数已经线程安全的情况下,这个函数新建一个内存区来保存信息明显是浪费空间和时间的选择。
这个函数大致参数与CreateThread相同,只是返回值类型为uintptr_t ,则对于新建一个线程并返回线程句柄需要强制转换为HANDLE类型,
线程函数的类型为 unsigned __stdcall fun(void * );
//第1个参数:安全属性,NULL为默认安全属性
//第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0
//第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址)
//第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针
//第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂)
//第6个参数:用于记录线程ID的地址
uintptr_t _beginthreadex( // NATIVE CODE
void *security,
unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
分享到:
相关推荐
C++多线程 windows
C++多线程的十个例子,学习window下多线程编程
C++多线程编程
P303.zip
学习C++多线程,C++多线程编程入门!
C++多线程编程实战 ,姜佑译(2018年PDF高清).rar C++多线程编程实战 ,姜佑译(2018年PDF高清).rar
c++ 多线程编程之三 线程间通讯 后面还有四哦
c++多线程编程,帮助我们学习多线程,对于新老学者都有很大的帮助
C++多线程编程入门教程,讲解了多线程的概念,并且给出了linux和windows平台下多线程实现的例子。。
C++多线程编程实战 姜佑译
本文简介了pthread的用法,介绍了多核多线程编程的入门知识
C++11多线程编程.zip 代码实例 C++11多线程编程future其他成员函数、shared_future、atomic C++11多线程编程std__atomic续谈、std__async深入谈 C++11多线程编程windows临界区、其他各种mutex互斥量 C++11多线程编程...
从CSDN上整理的一点资源贡献给大家,讲述了C++ 利用WinAPI函数进行多线程编程的详解
C++面向多线程编程
Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理...Visual C++ 6.0中,使用MFC类库也实现了多线程的程序设计,使得多线程编程更加方便。 该教程提供了由浅入深的讲解及Demo,对初学多线程编程很有帮助。
Visual C++ 多线程编程,CreateThread,CreateMutex,WaitForSingleObject等函数的应用
c++高级编程 C++面向对象多线程编程 c++标准程序库.pdf