本篇文章主要介绍了"windows多线程编程 windows多线程编程星球(一)",主要涉及到windows多线程编程方面的内容,对于Windows 7jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下:
以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分。原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这...
关于Mutex是怎样实现资源的同步与控制的,按理说他也是一条条的指令,为啥它就不能被线程切换打断而SetConsoleCursorPosition就能呢?这里首先要说到的是原子操作,对于原子操作的定义是这样的:如果这个操作所处的层(layer)的更高层不能发现其内部实现与结构。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。简单点的说就是原子操作不同于普通的指令操作,它是不可以被打断的,要么一次性执行完,要么一个也不执行。原子操作的实现是一个很深度也很具有技术难度的问题,具体的有兴趣的话可以查看http://www.cnblogs.com/fanzhidongyzby/p/3654855.html。而对于Mutex对象包含: 一个线程 ID ,使用计数和递归计数 。线程 ID 表示当前占用该互斥量的线程 ID ,递归计数表示该线程占用互斥量的次数,使用计数表示使用互斥量对象的不同线程的个数。通过这三个元素,Mutex才能完成同步与控制。这里还想扯扯的就是CreateMutex的第二个参数,如果第二个参数是ture,那么表示当前创建Mutex的线程拥有该mutex对象,也就是说当前线程先占用了该Mutex对象,在该线程调用ReleaseMutex之前,别的线程是无法通过WaitForSingleObject等待这个Mutex的。而ReleaseMutex的具体作用是每调用它一次将互斥对象的计数器减一,直到减到零为止,此时释放互斥对象,并将互斥对象中的线程id 置零。它的使用条件是,互斥对象在哪个线程中被创建,就在哪个线程里面释放。因为调用的时候会检查当前线程的id是不是与互斥对象中保存的id一致,若一致,则此次操作有效,不一致,则无效。
五、命令与控制。
从前面到这里,planet里面定义的resource属性到现在还没有使用,那么在这一节,我准备使用上这个属性。在我任性的逻辑里面我准备这样做,子星球每前进一步消耗一点资源,然后将这个资源输出在console的屏幕上的某个位置。那末就先构造好这个资源显示函数:
void UpdatePlanetResource(struct Planet &p)
{
char cRes[3];
itoa(p.resource,cRes,10);
if( p.type == 1 )
{
MoveOutputToPos(2,0,cRes,true);
}
else
{
MoveOutputToPos(1,p.index*3,cRes,true);
}
}
这个函数就是根据不同的星球类型显示目前他的资源数字。在我们的程序中,我们需要时时的更新这些资源数据,那么看起来应该很简单的一个问题,分别在主线程和子线程中相应位置调用这个函数就好了。仔细看一下这个想法,会发现一个问题,在我们的设计中,母星球旋转的速度和子星球前进的速度并不一样,母星球显示刷新周期是80ms而子星球是500ms,也就是说子星球没500ms消耗一点资源而这个时候母星球已经刷新了四个周期了。这样的话会有一个很现实的问题,你无法实现两个资源消耗额度的同步刷新。如果你单纯的只是在两个星球的while循环中调用上面的函数,你会发现两个资源的增加与减少并不同步。这时候会想到有没有一种办法,当子星球消耗了一点资源的时候才去通知母星球,然后让它去更新一下自己的资源?
为了解决成千上万和这个问题一样的问题,windows多线程编程中提供了一个叫Event的对象来实现这一通知响应机制。要使用Event,首先还得创建一个handle对象作为CreateEvent的返回值,类似于CreateMutex:
hEvent = CreateEvent( NULL , FALSE , FALSE , NULL );
相比于CreateMutex函数,CreateEvent有四个参数,第一个和最后一个参数的意义和CreateMutex相同。那么就只需要介绍一下第二个,第三个参数,第二个参数是是否手工设置状态,第三个是Event的初始状态是啥。要具体解释一下这两个参数就要先解释一下Event的状态,和Mutex一样作为一个内核对象,Event也有激活态和非激活态。如果第二个参数是false,那么在每次获得激活状态的Event对象之后,Event对象会自动设置为未激活状态,反之,则需要手工调用ResetEvent将其设置为未激活状态。第三个参数如果是True,那么这个Event的初始状态就是激活的,反之则是未激活的。