实现redis 数据库同步机制制有哪些方法

后使用快捷导航没有帐号?
 论坛入口:
  |   |    |   | 
浅谈RTS游戏网络同步:3种同步机制模式的实现
设计思想/框架&服务器&
QQ截图53.jpg (88.59 KB, 下载次数: 13)
15:43 上传
  GameRes游资网授权发布 文 / 王耀威
  RTS游戏有很多,可能大家比较熟悉的有Warcraft III (dota)和 StarCraft,早期西木的沙丘,红色警戒更是rts游戏的鼻祖,带给我们无限的欢乐和回忆。还有当下比较流行lol与dota2,实际上都是孙子辈的游戏了。
  RTS游戏同步很重要,而且同步也能非常稳定地实现。的那么他们到底是怎么做到高频操作又同步的呢?
  同步机制
  假设游戏中A,B两个玩家移动,并同时向对方发出射击指令,如果没有合适的同步机制,那么可能出现的情况有:
A屏幕显示B已经被杀死,B屏幕显示A已经被杀死或者在瞄准后确打不到对方
  图中玩家Plyaer1,Plyaer2在两个不同的客户端,表现出不同效果:
1.png (113.06 KB, 下载次数: 14)
15:41 上传
  因为网络是有延时的,而每个玩家的网络情况都不尽相同。还有每帧渲染的延迟(早期的计算机性能不够好的时候会出现这个问题)
  同步机制最重要的作用就是解决延迟等可能发生不一致的情况。
  同步机制的分类
  Peer-to-peer模式:
  没有服务器,每个玩家互相连接,各自模拟整个流程.典型的lockstep模式
  优点:减少主机带来的延时
  缺点:容易作弊
2.png (18.22 KB, 下载次数: 12)
15:41 上传
  Client-Server模式
  所有的操作需经过服务器确认后才能进行客户端模拟,如arpg传奇类都是此架构,如果延时高就会有明显的卡顿。
  优点:服务器是绝对的权威,可以防止作弊,可以做更多的管理与限制
  缺点:服务器变的更复杂,服务器断线,所有玩家断线,属于服务器依赖型。
3.png (8.59 KB, 下载次数: 14)
15:41 上传
  早期的RTS游戏大多采用Lockstep方案来设计,像罗马帝国,沙丘之类。
  Lockstep最早用于军队中:
4.png (380.75 KB, 下载次数: 12)
15:41 上传
  就是说玩家的数据每个时间段同步一次,同步的走。
  标准的lockstep模式
每个玩家互相连接,整个游戏过程划分成一组turn指令帧,由玩家自我模拟游戏速度取决于网络最慢的那个玩家一个玩家掉线不会影响到其他玩家
  什么是Turn?
  一个turn可以理解成1个回合,相信大家都玩过回合制游戏吧,只是这个turn非常短,大概100MS-200MS。玩家相互之间发送的指令在每个turn间隔发出。
5.png (18.67 KB, 下载次数: 14)
15:41 上传
  每个玩家只需要接收指令,并在本地播放指令就可以啦。
  War3如何运算伤害?
  玩家到底是发送什么指令到主机,主机到底参与了什么计算呢?
  实际上玩家都只需要发送基本的指令如选择单位,移动单位,使用技能1234,点击物品栏1-6,可以通过APM查看软件看到一些基本操作事件。
6.png (20.39 KB, 下载次数: 12)
15:41 上传
  也就是说所有的一切伤害计算都是在本地计算完成的。
  包括伤害,暴击,命中,刷怪等,只要初始化好随机数种子就可以啦。
  玩家只是发送操作指令,如点击坐标(0,1, 0),左键框选(100,100,50,50)等。
  每个玩家都在模拟全部的流程。
  那么War3到底算不算使用lockstep模式,或者是特殊的client-server?
  其实可以通过几个问题判断出:
非主机玩家卡是否可以影响到其他玩家,如果不会,那么更可能是client-server模式可以通过抓包工具拦截网络数据包的流向,来判断是否是peer to peer的连接方式还是只连接到主机(或通过主机强制掉线方式判断)。
  一个外国朋友的回答:
7.png (122.71 KB, 下载次数: 12)
15:41 上传
  个人也认为War3是基于Client-Server的一种的特殊模式,主机肯定需要验证一些逻辑。
  主机负责广播每个client的指令,
  这存在两个问题:
本机(非主机)发出的指令,如果超时或者丢包,是否直接丢弃?其他玩家的指令,主机转发未成功确认,如何处理?
  第一个问题
  1.如果是本机(非主机)发出的指令超时,可以直接丢弃。(如果不丢弃,其他玩家就必须等待结果,这样会导致挂起,而且会非常频繁,这里还有udp协议容易丢包的原因,但是war3好像并没有经常性的挂起)
  还有一种可能,客户端得知之前的turn没有发送成功,把当前这轮的指令和上一轮的指令进行合并,然后一起发出,这样本地客户端就不会有任何的异样了。
  例如玩家移动到A后再移动到B
  上个turn的指令是移动到A点,但是没有发成功,下个turn的指令先移动到A,再移动到B,这样在客户端就不会有丢失的感觉啦,还是可以正常的模拟而不会影响到其他玩家。
  2. 收其他玩家的指令超时,那么属于我们自身网络的问题,如果丢弃必将导致游戏进程不同步,所以服务器必须将他们的turn指令都缓存起来,
  或者缓存一部分turn指令集,在我网络稳定的时候,把丢失的那一部分turn指令集发给我,而我只需要下载那个list加快gameupdate就好啦。
  关于外挂的问题
  相信玩过魔兽的人基本都用过,实际上像战争迷雾,显示单位等只会保存一个状态值在内存中,只要定位到内存地址,改一下变量值就好了,一般是服务器是不会检测这个的。
  而攻击力,道具数量等,由于大家都需要模拟,你本地修改了,会影响到其他人,程序就会发生蝴蝶效应。
  开图挂应该是这类游戏最常见的了。
8.png (263.75 KB, 下载次数: 12)
15:41 上传
9.png (205.51 KB, 下载次数: 12)
15:41 上传
  至于现在非常流行的 Dota2 和 英雄联盟,会额外的加入更多服务器来验证和计算一些外部数据,但内部原理是一致的,早期的游戏与现在的网游不可同日而语。
  相关阅读:
关注我们官方微信公众号
下载我们官方APP-游戏行
关注手游动态微信公众号
适用于游戏设计中的72个心理学效应理论香锅再次被罚!电竞战队管理愈发严格规范1月15日—1月21日共有52款游戏开测|GameRe《炉石传说》早期游戏设计历程回顾张小龙微信公开课演讲:跳一跳DAU达到了1.7微信、QQ等热门应用不见了 都是App Store竞
微信扫一扫关注我们→A: The code segments within a program that access the same
object from
separate, concurrent threads are called “critical
sections”。
翻译:在一个程序当中代码段访问了同一个对象从单独的并发的线程当中,那么这个代码段叫”临界区”
怎么解决呢:使用同步的机制对临界区进行保护
同步的两种方式:同步块和同步方法
对于同步来说都是使用synchronized方法
每一个对象都有一个监视器,或者叫做锁。 同步块实例
class Tickets { public static void main(String[] args)
sellTickets st = new sellTickets(); //四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); new Thread(st).start();
} class sellTickets implements Runnable { int ticket = 100;
Object o = new Object();
@Override public void run() { while(true)
{ //每一个对象都有一个监视器,或者叫做锁。同步块示例 synchronized (o) { if(ticket & 0)
{ //存在的隐藏的问题当ticket=1,它的时间片到期了进入到if语句中,第二个线程进入到if语句然后时间片到期 try { //线程睡眠,该方法需要写异常 Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} //第几个线程卖出了第多少张票 System.out.println(Thread.currentThread().getName() + &sell tickets& + ticket);
题目是不是有问题啊??问的是异步机制,但是答案怎么是同步的??
题中进程应该改成线程吧,否则是不是要选B
简单来说,监视器用来监视线程进入这个特别房间,他确保同一时间只能有一个线程可以访问特殊房间中的数据和代码。
监视器:sysnchronized(Object o); o若为普通属性 o就是同步监视器
若为静态属性 则该类为同步监视器
相当于synchronized(O.class)
public synchronized void test(){} 同步监视器为调用该方法的对象
题目出错了,应该是线程。
原来监视器也叫锁,长知识了
”monitor”
是操作系统实现同步的重要基础概念,同样它也用在JAVA的线程同步中,
在语法的表现就是synchronized
Java语言是运行在敏感词ava虚拟机平台上的敏感词ava的多进程和多线程机制也是由敏感词ava虚拟机实现的,。因此敏感词ava进程间的异步执行是由敏感词ava虚拟机实现的。
是7乒乒乓乓去输cvp入GPU888888CCD ccü
原来监视器指的是锁
我的答案是A
首先jvm中没有进程的概念 ,但是jvm中的线程映射为操作系统中的进程,对应关系为1:1。那这道题的问的就是jvm中线程如何异步执行 。
在jvm中 是使用监视器锁来实现不同线程的异步执行,
在语法的表现就是synchronized
同步代码块
监视器又称锁
jvm中监视器知识点
在一个程序当中代码段访问了同一个对象从单独的并发的线程当中,那么这个代码段叫”临界区”
怎么解决呢:使用同步的机制对临界区进行保护
同步的两种方式
:同步块和同步方法
对于同步来说都是使用synchronized方法
每一个对象都有一个
,或者叫做
机制实现了进程之间的异步执行
可以这样理解,程序中有两个进程A和B,A由于需要的资源被占用而被阻塞,这时候进程B还是在运行,而A可以使用监视器来判断它所需要的资源有没有来,当A所需要的资源来的时候A继续执行!
这道题你会答吗?花几分钟告诉大家答案吧!
扫描二维码,关注牛客网
下载牛客APP,随时随地刷题
浙ICP备号-2
扫一扫,把题目装进口袋> 问题详情
多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
悬赏:0&答案豆
提问人:匿名网友
发布时间:
多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
为您推荐的考试题库
您可能感兴趣的试题
1在LC正弦波振荡电路中,不用通用型集成运算放大器作放大电路的原因是其上限截止频率太低,难以产生高频振荡信号。
)2当集成运放工作在非线性区时,输出电压不是高电平,就是低电平。
)3一般情况下,电压比较器的集成运算放大器工作在开环状态,或者引入了正反馈。
我有更好的答案
请先输入下方的验证码查看最佳答案
图形验证:
验证码提交中……
找答案会员
享三项特权
找答案会员
享三项特权
找答案会员
享三项特权
选择支付方式:
支付宝付款
郑重提醒:支付后,系统自动为您完成注册
请使用微信扫码支付(元)
支付后,系统自动为您完成注册
遇到问题请联系在线客服QQ:
请您不要关闭此页面,支付完成后点击支付完成按钮
遇到问题请联系在线客服QQ:
恭喜您!升级VIP会员成功
提示:请截图保存您的账号信息,以方便日后登录使用。
常用邮箱:
用于找回密码
确认密码:进程线程同步的四种方法
我的图书馆
进程线程同步的四种方法
  很想整理一下自己对进程线程同步互斥的理解。正巧周六一个刚刚回到学校的同学请客吃饭。在吃饭的过程中,有两个同学,为了一个问题争论的面红耳赤。一个认为.Net下的进程线程控制模型更加合理。一个认为Java下的线程池策略比.Net的好。大家的话题一下转到了进程线程同步互斥的控制问题上。回到家,想了想就写了这个东东。  现在流行的进程线程同步互斥的控制机制,其实是由最原始最基本的4种方法实现的。由这4种方法组合优化就有了.Net和Java下灵活多变的,编程简便的线程进程控制手段。  这4种方法具体定义如下 在《操作系统教程》ISBN 7- 一书中可以找到更加详细的解释    1临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。  2互斥量:为协调共同对一个共享资源的单独访问而设计的。  3信号量:为控制一个具有有限数量用户资源而设计。    4事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。    临界区(Critical Section)  保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。  临界区包含两个操作原语:EnterCriticalSection() 进入临界区LeaveCriticalSection() 离开临界区  EnterCriticalSection()语句执行后代码将进入临界区以后无论发生什么,必须确保与之匹配的LeaveCriticalSection()都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。  MFC提供了很多功能完备的类,我用MFC实现了临界区。MFC为临界区提供有一个CCriticalSection类,使用该类进行线程同步处理是非常简单的。只需在线程函数中用CCriticalSection类成员函数Lock()和UnLock()标定出被保护代码片段即可。Lock()后代码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。  //CriticalSection  CCriticalSection global_CriticalS  // 共享资源  char global_Array[256];  //初始化共享资源  void InitializeArray()  {   for(int i = 0;i&256;i++)   {   global_Array[i]=I;   }  }  //写线程  UINT Global_ThreadWrite(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   //进入临界区  global_CriticalSection.Lock();   for(int i = 0;i&256;i++)   {   global_Array[i]=W;   ptr-&SetWindowText(global_Array);   Sleep(10);   }  //离开临界区   global_CriticalSection.Unlock();   return 0;  }  //删除线程  UINT Global_ThreadDelete(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   //进入临界区   global_CriticalSection.Lock();   for(int i = 0;i&256;i++)   {   global_Array[i]=D;   ptr-&SetWindowText(global_Array);   Sleep(10);   }  //离开临界区   global_CriticalSection.Unlock();   return 0;  }  //创建线程并启动线程  void CCriticalSectionsDlg::OnBnClickedButtonLock()  {   //Start the first Thread   CWinThread *ptrWrite = AfxBeginThread(Global_ThreadWrite,   &m_Write,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);   ptrWrite-&ResumeThread();   //Start the second Thread   CWinThread *ptrDelete = AfxBeginThread(Global_ThreadDelete,   &m_Delete,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);   ptrDelete-&ResumeThread();  }  在测试程序中,Lock UnLock两个按钮分别实现,在有临界区保护共享资源的执行状态,和没有临界区保护共享资源的执行状态。    程序运行结果    互斥量(Mutex)    互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。  互斥量包含的几个操作原语:  CreateMutex() 创建一个互斥量  OpenMutex() 打开一个互斥量  ReleaseMutex() 释放互斥量  WaitForMultipleObjects() 等待互斥量对象  同样MFC为互斥量提供有一个CMutex类。使用CMutex类实现互斥量操作非常简单,但是要特别注意对CMutex的构造函数的调用  CMutex( BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL)  不用的参数不能乱填,乱填会出现一些意想不到的运行结果。  //创建互斥量  CMutex global_Mutex(0,0,0);  // 共享资源  char global_Array[256];  void InitializeArray()  {   for(int i = 0;i&256;i++)   {   global_Array[i]=I;   }  }  UINT Global_ThreadWrite(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   global_Mutex.Lock();   for(int i = 0;i&256;i++)   {   global_Array[i]=W;   ptr-&SetWindowText(global_Array);   Sleep(10);   }   global_Mutex.Unlock();   return 0;  }  UINT Global_ThreadDelete(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   global_Mutex.Lock();   for(int i = 0;i&256;i++)   {   global_Array[i]=D;   ptr-&SetWindowText(global_Array);   Sleep(10);   }   global_Mutex.Unlock();   return 0;  }  同样在测试程序中,Lock UnLock两个按钮分别实现,在有互斥量保护共享资源的执行状态,和没有互斥量保护共享资源的执行状态。    程序运行结果      信号量(Semaphores)  信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。  PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。  P操作申请资源:    (1)S减1;  (2)若S减1后仍大于等于零,则进程继续执行;  (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。  V操作 释放资源:  (1)S加1;  (2)若相加结果大于零,则进程继续执行;  (3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。  信号量包含的几个操作原语:  CreateSemaphore() 创建一个信号量  OpenSemaphore() 打开一个信号量  ReleaseSemaphore() 释放信号量  WaitForSingleObject() 等待信号量  //信号量句柄  HANDLE global_S  // 共享资源  char global_Array[256];  void InitializeArray()  {   for(int i = 0;i&256;i++)   {   global_Array[i]=I;   }  }  //线程1  UINT Global_ThreadOne(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   //等待对共享资源请求被通过 等于 P操作  WaitForSingleObject(global_Semephore, INFINITE);   for(int i = 0;i&256;i++)   {   global_Array[i]=O;   ptr-&SetWindowText(global_Array);   Sleep(10);   }  //释放共享资源 等于 V操作   ReleaseSemaphore(global_Semephore, 1, NULL);   return 0;  }  UINT Global_ThreadTwo(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   WaitForSingleObject(global_Semephore, INFINITE);   for(int i = 0;i&256;i++)   {   global_Array[i]=T;   ptr-&SetWindowText(global_Array);   Sleep(10);   }   ReleaseSemaphore(global_Semephore, 1, NULL);   return 0;  }  UINT Global_ThreadThree(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   WaitForSingleObject(global_Semephore, INFINITE);   for(int i = 0;i&256;i++)   {   global_Array[i]=H;   ptr-&SetWindowText(global_Array);   Sleep(10);   }   ReleaseSemaphore(global_Semephore, 1, NULL);   return 0;  }  void CSemaphoreDlg::OnBnClickedButtonOne()  {  //设置信号量 1 个资源 1同时只可以有一个线程访问   global_Semephore= CreateSemaphore(NULL, 1, 1, NULL);   this-&StartThread();  // TODO: Add your control notification handler code here  }  void CSemaphoreDlg::OnBnClickedButtonTwo()  {  //设置信号量 2 个资源 2 同时只可以有两个线程访问   global_Semephore= CreateSemaphore(NULL, 2, 2, NULL);   this-&StartThread();  // TODO: Add your control notification handler code here  }  void CSemaphoreDlg::OnBnClickedButtonThree()  {  //设置信号量 3 个资源 3 同时只可以有三个线程访问   global_Semephore= CreateSemaphore(NULL, 3, 3, NULL);   this-&StartThread();  // TODO: Add your control notification handler code here  }  信号量的使用特点使其更适用于对Socket(套接字)程序中线程的同步。例如,网络上的HTTP服务器要对同一时间内访问同一页面的用户数加以限制,这时可以为每一个用户对服务器的页面请求设置一个线程,而页面则是待保护的共享资源,通过使用信号量对线程的同步作用可以确保在任一时刻无论有多少用户对某一页面进行访问,只有不大于设定的最大用户数目的线程能够进行访问,而其他的访问企图则被挂起,只有在有用户退出对此页面的访问后才有可能进入。    程序运行结果    事件(Event)    事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。  信号量包含的几个操作原语:  CreateEvent() 创建一个信号量  OpenEvent() 打开一个事件  SetEvent() 回置事件  WaitForSingleObject() 等待一个事件  WaitForMultipleObjects()  等待多个事件  WaitForMultipleObjects 函数原型:  WaitForMultipleObjects(  IN DWORD nCount, // 等待句柄数  IN CONST HANDLE *lpHandles, //指向句柄数组  IN BOOL bWaitAll, //是否完全等待标志  IN DWORD dwMilliseconds //等待时间  )  参数nCount指定了要等待的内核对象的数目,存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。dwMilliseconds在这里的作用与在WaitForSingleObject()中的作用是完全一致的。如果等待超时,函数将返回WAIT_TIMEOUT。  //事件数组  HANDLE global_Events[2];  // 共享资源  char global_Array[256];  void InitializeArray()  {   for(int i = 0;i&256;i++)   {   global_Array[i]=I;   }  }  UINT Global_ThreadOne(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   for(int i = 0;i&256;i++)   {   global_Array[i]=O;   ptr-&SetWindowText(global_Array);   Sleep(10);   }  //回置事件   SetEvent(global_Events[0]);   return 0;  }  UINT Global_ThreadTwo(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");   for(int i = 0;i&256;i++)   {   global_Array[i]=T;   ptr-&SetWindowText(global_Array);   Sleep(10);   }  //回置事件   SetEvent(global_Events[1]);   return 0;  }  UINT Global_ThreadThree(LPVOID pParam)  {   CEdit *ptr=(CEdit *)pP   ptr-&SetWindowText("");  //等待两个事件都被回置   WaitForMultipleObjects(2, global_Events, true, INFINITE);   for(int i = 0;i&256;i++)   {   global_Array[i]=H;   ptr-&SetWindowText(global_Array);   Sleep(10);   }   return 0;  }  void CEventDlg::OnBnClickedButtonStart()  {   for (int i = 0; i & 2; i++)   {  //实例化事件   global_Events[i]=CreateEvent(NULL,false,false,NULL);   }   CWinThread *ptrOne = AfxBeginThread(Global_ThreadOne,   &m_One,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);   ptrOne-&ResumeThread();  //Start the second Thread   CWinThread *ptrTwo = AfxBeginThread(Global_ThreadTwo,   &m_Two,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);   ptrTwo-&ResumeThread();  //Start the Third Thread   CWinThread *ptrThree = AfxBeginThread(Global_ThreadThree,   &m_Three,   THREAD_PRIORITY_NORMAL,   0,   CREATE_SUSPENDED);   ptrThree-&ResumeThread();  // TODO: Add your control notification handler code here  }  事件可以实现不同进程中的线程同步操作,并且可以方便的实现多个线程的优先比较等待操作,例如写多个WaitForSingleObject来代替WaitForMultipleObjects从而使编程更加灵活。  程序运行结果    总结:    1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。    2. 互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。  3. 通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器。
TA的最新馆藏[转]&
喜欢该文的人也喜欢

我要回帖

更多关于 redis 同步机制 的文章

 

随机推荐