线程间怎么通讯/同步?之前在一个小系列中介绍了进程间通讯的方式,所以有些男子伴对进程间通讯和同步的方式很好奇。没关系。下边小编将继续给你们科普下进程间通讯和同步的方式。
线程间通讯及同步方式介绍:
一、线程间的通讯方法
1、使用全局变量
全局变量最好申明为volatile,主要是由于多线程可能会改变全局变量。
2、使用消息实现通讯
在Windows编程中,每位线程都可以有自己的消息队列(UI线程默认有自己的消息队列和消息循环,工作线程须要自动实现消息循环),所以消息可以拿来在线程之间传递sendMessage和postMessage。
1)定义消息#defineWM_thread_sendmsg=WM_user20;
2)添加消息函数申明afx_msgintontendmsg();();
3)添加消息映射ON_MESSAGE(WM_THREAD_SENDMSG,ontsm);
4)降低了OnTSM()的实现功能;
5)在线程函数中加入PostMessage消息Post函数。
3、使用风波CEvent类实现线程间通讯
风波对象有两种状态:有讯号和无讯号。线程可以监视处于讯号状态的风波,便于在适当的时间对风波执行操作。
1)创建CEvent类的对象:CEventthreadStart默认处于非通讯状态;
2)threadStart。SetEvent();使其处于交流状态;
3)调用WaitForSingleObject()来监视CEvent对象。
二、线程间的同步方法
每位线程都可以访问进程中的公共变量和资源,所以在使用多线程的过程中须要注意的问题是怎样避免两个或多个线程同时访问同一个数据,以免破坏数据的完整性。
数据之间的互相约束包括:
1.直接约束关系,即一个线程的处理结果是另一个线程的输入,所以直接约束线程,这可以称为同步关系。
2.间接约束关系,即两个线程须要访问同一个资源,而这个资源只能由一个线程同时访问。这些关系被称为线程之间对资源的互斥访问。从某种意义上说,互斥是约束关系较小的同步。
线程间同步有四种形式:
1、临界区
临界区对应于一个cccriticalsection对象。当线程须要访问受保护的数据时,会调用EnterCriticalSection函数。保护数据的操作完成后,调用LeaveCriticalSection函数,释放临界段对象的所有权,让另一个线程占据临界段对象,访问被保护的数据。
PS:关键段对象记录了拥有该对象的线程句柄,即它有“线程所有权”的概念,即步入代码段的线程可以在离开前反复步入关键代码区。为此,秘钥段可以用于线程之间的互斥,但不能用于同步(同步须要在一个线程中步入,在另一个线程中离开)。
2、互斥量
互斥和临界区类似,并且使用上去相对复杂(互斥是一个内核对象)。它除了可以实现同一应用程序的线程之间的同步,还可以实现不同进程之间的同步,进而实现资源的安全共享。
PS:
1)互斥也有线程所有权的概念,所以只能访问线程间互斥的资源,不会由于线程同步;
2)因为互斥体是一个内核对象,可以在进程间进行通讯,它还有一个挺好的特性,那就是完美解决了进程间通讯时的“放弃”问题。
3、信号量
讯号量的使用类似于互斥,只是它可以允许多个线程同时访问同一个资源,PV操作。
PS:风波可以完美解决线程之间的同步问题,讯号量也属于内核对象linux命令,可以用于进程间通讯。
4、事件
风波分为自动设置风波和手动设置风波。在风波风波内部linux线程间同步方式,它包含一个使用计数(所有内核对象都有),一个布尔值指示风波是自动设置的还是手动设置的,另一个布尔值指示风波是否被触发。由设置风波()触发,设置为不由重置风波()触发。
PS:风波是内核对象linux线程间同步方式,可以解决线程之间的同步问题国内linux主机,所以也可以解决互斥问题。
线程之间的通讯和同步方式到此结束。关于线程同步的更多文章,可以参考:《线程同步的方式有什么?Linux下实现线程同步的三种方式》