线程间怎么通讯/同步?此前小编给你们介绍了进程间通讯的方式,于是一些伙伴又好奇线程间的通讯及同步方式,没关系,下边小编就继续给你们科普下线程间通讯及同步的方式。
线程间通讯及同步方式介绍:
一、线程间的通讯方法
1、使用全局变量
主要因为多个线程可能修改全局变量,因而全局变量最好申明为volatile。
2、使用消息实现通讯
在Windows程序设计中,每一个线程都可以拥有自己的消息队列(UI线程默认自带消息队列和消息循环linux线程间同步方式,工作线程须要自动实现消息循环),因而可以采用消息进行线程间通讯sendMessage,postMessage。
1)定义消息#defineWM_THREAD_SENDMSG=WM_USER+20;
2)添加消息函数申明afx_msgintOnTSendmsg();
3)添加消息映射ON_MESSAGE(WM_THREAD_SENDMSG,OnTSM);
4)添加OnTSM()的实现函数;
5)在线程函数中添加PostMessage消息Post函数。
3、使用风波CEvent类实现线程间通讯
Event对象有两种状态:有讯号和无讯号,线程可以监视处于有讯号状态的风波,便于在适当的时侯执行对风波的操作。
1)创建一个CEvent类的对象:CEventthreadStart;它默认处在未通讯状态;
2)threadStart.SetEvent();使其处于通讯状态;
3)调用WaitForSingleObject()来监视CEvent对象。
二、线程间的同步方法
各个线程可以访问进程中的公共变量,资源,所以使用多线程的过程中须要注意的问题是怎样避免两个或两个以上的线程同时访问同一个数据,以免破坏数据的完整性。
数据之间的互相掣肘包括:
1、直接阻碍关系,即一个线程的处理结果,为另一个线程的输入,因而线程之间直接阻碍着,这些关系可以称之为同步关系。
2、间接阻碍关系,即两个线程须要访问同一资源,该资源在同一时刻只能被一个线程访问,这些关系称之为线程间对资源的互斥访问,某种意义上说互斥是一种阻碍关系更小的同步。
线程间的同步方法有四种:
1、临界区
临界区对应着一个CcriticalSection对象,当线程须要访问保护数据时,调用EnterCriticalSection函数;当对保护数据的操作完成以后,调用LeaveCriticalSection函数释放对临界区对象的拥有权,以使另一个线程可以夺回临界区对象并访问受保护的数据。
PS:关键段对象会记录拥有该对象的线程句柄即其具有“线程所有权”概念,即步入代码段的线程在leave之前,可以重复步入关键代码区域。所以关键段可以用于线程间的互斥,但不可以用于同步(同步须要在一个线程步入,在另一个线程leave)。
2、互斥量
互斥与临界区很相像linux线程间同步方式,而且使用时相对复杂一些(互斥量为内核对象),除了可以在同一应用程序的线程间实现同步,还可以在不同的进程间实现同步,进而实现资源的安全共享。
PS:
1)互斥量因为也有线程所有权的概念,故也只能进行线程间的资源互斥访问,不能因为线程同步;
2)因为互斥量是内核对象,因而其可以进行进程间通讯,同时还具有一个挺好的特点,就是在进程间通讯时完美的解决了“遗弃”问题。
3、信号量
讯号量的用法和互斥的用法很相像,不同的是它可以同一时刻允许多个线程访问同一个资源,PV操作。
PS:风波可以完美解决线程间的同步问题linux 命令,同时讯号量也属于内核对象,可用于进程间的通讯。
4、事件
风波分为自动置位风波和手动置位风波。风波Event内部它包含一个使用计数(所有内核对象都有),一个布尔值表示是自动置位风波还是手动置位风波,另一个布尔值拿来表示风波有无触发。由SetEvent()来触发,由ResetEvent()来设成未触发。
PS:风波是内核对象,可以解决线程间同步问题,因而也能解决互斥问题。
关于线程间的通讯及同步方式就给你们讲解到这儿了arch linux,更多关于线程同步的文章,你们可以参考:《线程同步的方式有什么?Linux下实现线程同步的三种方式》