您现在的位置是:首页
>
同步执行顺序图 执行绪同步详细资料大全
执行绪同步详细资料大全 执行绪同步:即当有一个执行绪在对记忆体进行操作时,其他执行绪都不可以对这个记忆体地址进行操作,直到该执行绪完成操作, 其他执行绪才能对该记忆体地址进行操作,而其他执行绪又处于等
执行绪同步详细资料大全

执行绪同步:即当有一个执行绪在对记忆体进行操作时,其他执行绪都不可以对这个记忆体地址进行操作,直到该执行绪完成操作, 其他执行绪才能对该记忆体地址进行操作,而其他执行绪又处于等待状态,实现执行绪同步的方法有很多,临界区对象就是其中一种。
基本介绍
中文名:执行绪同步外文名:thread synchronization类型:理论套用:物理定义:协同步调,按预定的先后次序进行 简介,举例说明,执行绪同步的方式和机制,作用,方法,简介
在一般情况下,创建一个执行绪是不能提高程式的执行效率的,所以要创建多个执行绪。但是多个线程同时运行的时候可能调用执行绪函式,在多个执行绪同时对同一个记忆体地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆蓋,所以就要使执行绪同步。 同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。 “同”字从字面上容易理解为一起动作 其实不是,“同”字应是指协同、协助、互相配合。 如进程、执行绪同步,可理解为进程或执行绪A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它执行绪也不能调用这个方法。按照这个定义,其实绝大多数函式都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。例如Window API函式SendMessage。该函式传送一个讯息给某个视窗,在对方处理完讯息之前,这个函式不返回。当对方处理完毕以后,该函式才把讯息处理函式所返回的LRESULT值返回给调用者。 在多执行绪编程里面,一些敏感数据不允许被多个执行绪同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个执行绪访问,以保证数据的完整性。举例说明
在Java里面,通过synchronized进行同步的保证。例如:class MyTest{private static final Object lock=new Object();public static synchronized void test(){同步的方法}public void test2(){synchronized(lock){方法级同步,也可以使用this实现对象级同步}}} 在C++ 11里面,通过std::mutex的加锁和解锁来保证。例如:#include<mutex>#include<thread>usingnamespacestd;mutexm;voidthreadFunc(inti){m.lock();在这里写上你需要的代码m.unlock();}intmain(){threadt1(threadFunc,1);threadt2(threadFunc,2);t1.join();t2.join();return0;}执行绪同步的方式和机制
临界区(Critical Section)、互斥对象(Mutex):主要用于互斥控制;都具有拥有权的控制方法,只有拥有该对象的执行绪才能执行任务,所以拥有,执行完任务后一定要释放该对象。 信号量(Semaphore)、事件对象(Event):事件对象是以通知的方式进行控制,主要用于同步控制! 1、临界区:通过对多执行绪的串列化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个执行绪对共享资源进行访问,如果有多个执行绪试图访问公共资源,那么在有一个执行绪进入后,其他试图访问公共资源的执行绪将被挂起,并一直等到进入临界区的执行绪离开,临界区在被释放后,其他执行绪才可以抢占。它并不是核心对象,不是属于作业系统维护的,而是属于进程维护的。 总结下关键段: 1)关键段共初始化化、销毁、进入和离开关键区域四个函式。 2)关键段可以解决执行绪的互斥问题,但因为具有“执行绪所有权”,所以无法解决同步问题。 3)推荐关键段与旋转锁配合使用。 2、互斥对象:互斥对象和临界区很像,采用互斥对象机制,只有拥有互斥对象的执行绪才有访问公共资源的许可权。因为互斥对象只有一个,所以能保证公共资源不会同时被多个执行绪同时访问。当前拥有互斥对象的执行绪处理完任务后必须将执行绪交出,以便其他执行绪访问该资源。 总结下互斥量Mutex: 1)互斥量是核心对象,它与关键段都有“执行绪所有权”所以不能用于执行绪的同步。 2)互斥量能够用于多个进程之间执行绪互斥问题,并且能解决某进程意外终止所造成的“遗弃”问题。 3、信号量:信号量也是核心对象。它允许多个执行绪在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大执行绪数目 在用CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设定为最 大资源计数,每增加一个执行绪对共享资源的访问,当前可用资源计数就会减1 ,只要当前可用资源计数是大于0 的,就可以发出信号量信号。但是当前可用计数减小 到0 时则说明当前占用资源的执行绪数已经达到了所允许的最大数目,不能在允许其他执行绪的进入,此时的信号量信号将无法发出。执行绪在处理完共享资源后,应在离 开的同时通过ReleaseSemaphore ()函式将当前可用资源计数加1 。在任何时候当前可用资源计数决不可能大于最大资源计数。 4、事件对象: 通过通知操作的方式来保持执行绪的同步,还可以方便实现对多个执行绪的优先权比较的操作 总结下事件Event 1)事件是核心对象,事件分为手动置位事件和自动置位事件。事件Event内部它包含一个使用计数(所有核心对象都有),一个布尔值表示是手动置位事件还是自动置位事件,另一个布尔值用来表示事件有无触发。 2)事件可以由SetEvent()来触发,由ResetEvent()来设成未触发。还可以由PulseEvent()来发出一个事件脉冲。 3)事件可以解决执行绪间同步问题,因此也能解决互斥问题。作用
执行绪有可能和其他执行绪共享一些资源,比如,记忆体,档案,资料库等。 当多个执行绪同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入执行绪“同步”机制,即各位执行绪之间要有个先来后到,不能一窝蜂挤上去抢作一团。 执行绪同步的真实意思和字面意思恰好相反。执行绪同步的真实意思,其实是“排队”:几个执行绪之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。方法
执行绪同步的方法: (1)wait():使一个执行绪处于等待状态,并且释放所持有的对象的lock。 (2)sleep():使一个正在运行的执行绪处于睡眠状态,是一个静态方法,调用此方法要捕捉 InterruptedException异常。 (3)notify():唤醒一个处于等待状态的执行绪,注意的是在调用此方法的时候,并不能确切的 唤醒某一个等待状态的执行绪,而是由JVM确定唤醒哪个执行绪,而且不是按优先权。 (4)notityAll ():唤醒所有处入等待状态的执行绪,注意并不是给所有唤醒执行绪一个对象的锁, 而是让它们竞争。 很赞哦! (1068)