安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

Windows线程同步的四种方式

12月4日 牵手手投稿
  为什么要进行线程同步
  在多线程的程序中,很少有多个线程能在其生命期内进行完全独立的操作;通常情况是一些线程进行某些操作,而其他的线程必须对其操作后的结果进行了解。如果不采取同步机制,其他线程会在线程处理任务前访问处理结果,这样会产生错误的了解。例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题;若一个线程负责写操作,其他线程负责读取操作,则不能保证读取的就是修改过的值,这时就必须在变量写操作过程时加上访问限制,在写操作完成后解除访问限制。这种保证线程能正确获取其他线程处理结束后的结果的措施称为线程同步。
  线程同步的四种方式:
  同步方式
  速度、资源开销
  跨进程
  资源统计
  CriticalSection
  速度快、非内核对象
  不能用于不同进程
  不能资源统计(每次只能有一个线程对共享资源进行存取)
  Mutex
  速度慢,内核对象
  可用于不同进程
  不能资源统计
  Semaphore
  速度慢、内核对象
  可用于不同进程
  可资源统计(可以让一个或多个线程对共享资源进行存取)
  Event
  速度慢、内核对象
  可用于不同进程
  可资源统计CriticalSection
  临界区(CriticalSection):通过对多线程的串行化来访问公共资源或一段代码,本身不是内核对象,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开。临界区被释放后,其他线程才可以抢占。
  【初始化临界区】VOIDWINAPIInitializeCriticalSection(LPCRITICALSECTIONlpCriticalSection);
  【删除临界区】VOIDWINAPIDeleteCriticalSection(LPCRITICALSECTIONlpCriticalSection);
  【获取临界区】VOIDWINAPIEnterCriticalSection(LPCRITICALSECTIONlpCriticalSection);
  【释放临界区】VOIDWINAPILeaveCriticalSection(LPCRITICALSECTIONlpCriticalSection);
  临界区在使用时,以CRITICALSECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数占有和释放一个临界区。所用到的CRITICALSECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。
  【示例】includeiostreamincludecstdlibincludecstdioincludectimeincludewindows。hintcountervalue0;countervalueintmaxcounter5;countervaluemaxintmincounter0;countervalueminintproducernum0;生产者进入临界区次数intconsumernum0;消费者进入临界区次数CRITICALSECTION临界区DWORDWINAPIproducer(LPVOIDparam){intid(int)while(true){Sleep(rand()1000);srand(countervalue);EnterCriticalSection(criticalsection);intaddcountrand()61;判断是否超过最大值if(countervaluemaxcounter){if(countervaluemaxcounter){}printf(Producerd:producedditems,id,addcount);}else{printf(Producerd:countervalueisfull,cancelproducing。。。,id);}printf(itemsnumisd,countervalue);LeaveCriticalSection(criticalsection);生产者进入临界区,次数增加}}DWORDWINAPIconsumer(LPVOIDparam){intid(int)while(true){sleepforarandomperiodoftimeSleep(rand()1000);EnterCriticalSection(criticalsection);generatesrand(countervalue);intdecreasecountrand()61;判断是否超过最小值if(countervaluemincounter){if(countervaluemincounter){}printf(Consumerd:consumedditems,id,decreasecount);}else{printf(Consumerd:countervalueislessthanmixinum,cancelconsuming。。。,id);}printf(itemsnumisd,countervalue);LeaveCriticalSection(criticalsection);消费者进入临界区,次数增加}return0;}intmain(){srand(countervalue);intthreadproducer5;intthreadconsumer5;intpvalue〔5〕{0};生产者intcvalue〔5〕{0};消费者DWORDthreadpid〔5〕,threadcid〔5〕;HANDLEhthreadp〔5〕,hthreadc〔5〕;生产者和消费者线程InitializeCriticalSection(criticalsection);FILEfreopens(fp,CriticalSectionoutput。txt,w,stdout);createproducerthreadfor(inti0;i){pvalue〔i〕i1;hthreadp〔i〕CreateThread(NULL,0,producer,pvalue〔i〕,0,threadpid〔i〕);}createconsumerthreadfor(inti0;i){cvalue〔i〕i1;hthreadc〔i〕CreateThread(NULL,0,consumer,cvalue〔i〕,0,threadcid〔i〕);}Sleep(1000);for(inti0;i){WaitForSingleObject(hthreadp〔i〕,INFINITE);}for(inti0;i){WaitForSingleObject(hthreadc〔i〕,INFINITE);}DeleteCriticalSection(criticalsection);fclose(stdout);return0;}Mutex
  互斥量(Mutex):只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
  【创建互斥量】HANDLEWINAPICreateMutex(LPSECURITYATTRIBUTESlpMutexAttributes,pointertosecurityattributesBOOLbInitialOwner,flagforinitialownershipLPCTSTRlpNamepointertomutexobjectname);参数意义:lpMutextAttributes传递安全相关的配置信息,使用默认安全设置时可以传递NULLbInitialOwner如果为TRUE,则创建出的互斥量对象属于调用该函数的线程,同时进入nonsignaled状态;如果为FALSE,则创建出的互斥量对象不属于任何线程,此时状态为signaledlpName用于命名互斥量对象。传入NULL时创建无名的互斥量对象
  【销毁互斥量】BOOLWINAPICloseHandle(HANDLEhObject);
  【获取互斥量】获取函数Windows线程创建中介绍的此函数,用于针对单个内核对象验证signaled。DWORDWINAPIWaitForSingleObject(HANDLEhHandle,handletoobjecttowaitforDWORDdwMillisecondstimeoutintervalinmilliseconds);
  【释放互斥量】BOOLWINAPIReleaseMutex(HANDLEhMutex需要释放的对象的句柄);
  互斥量被某一线程获取时为nonsignaled状态,释放时进入signaled状态。因此,可以利用WaitForSingleObject函数验证互斥量是否已分配。互斥量在WaitForSingleObject函数返回时自动进入nonsignaled状态,因为它是autoreset模式的内核对象。
  【示例】includeiostreamincludecstdlibincludecstdioincludectimeincludewindows。hintcountervalue0;countervalueintmaxcounter5;countervaluemaxintmincounter0;countervalueminintproducernum0;生产者进入临界区次数intconsumernum0;消费者进入临界区次数HANDLEMutexNULL;互斥锁DWORDWINAPIproducer(LPVOIDparam){intid(int)while(true){Sleep(rand()1000);srand(countervalue);WaitForSingleObject(Mutex,INFINITE);intaddcountrand()61;判断是否超过最大值if(countervaluemaxcounter){if(countervaluemaxcounter){}printf(Producerd:producedditems,id,addcount);}else{printf(Producerd:countervalueisfull,cancelproducing。。。,id);}printf(itemsnumisd,countervalue);ReleaseMutex(Mutex);生产者进入临界区,次数增加}}DWORDWINAPIconsumer(LPVOIDparam){intid(int)while(true){sleepforarandomperiodoftimeSleep(rand()1000);WaitForSingleObject(Mutex,INFINITE);generatesrand(countervalue);intdecreasecountrand()61;判断是否超过最小值if(countervaluemincounter){if(countervaluemincounter){}printf(Consumerd:consumedditems,id,decreasecount);}else{printf(Consumerd:countervalueislessthanmixinum,cancelconsuming。。。,id);}printf(itemsnumisd,countervalue);ReleaseMutex(Mutex);消费者进入临界区,次数增加}return0;}intmain(){srand(countervalue);intthreadproducer5;intthreadconsumer5;intpvalue〔5〕{0};生产者intcvalue〔5〕{0};消费者DWORDthreadpid〔5〕,threadcid〔5〕;HANDLEhthreadp〔5〕,hthreadc〔5〕;生产者和消费者线程MutexCreateMutex(NULL,FALSE,NULL);FILEfreopens(fp,CriticalSectionoutput。txt,w,stdout);createproducerthreadfor(inti0;i){pvalue〔i〕i1;hthreadp〔i〕CreateThread(NULL,0,producer,pvalue〔i〕,0,threadpid〔i〕);}createconsumerthreadfor(inti0;i){cvalue〔i〕i1;hthreadc〔i〕CreateThread(NULL,0,consumer,cvalue〔i〕,0,threadcid〔i〕);}Sleep(1000);for(inti0;i){WaitForSingleObject(hthreadp〔i〕,INFINITE);}for(inti0;i){WaitForSingleObject(hthreadc〔i〕,INFINITE);}CloseHandle(Mutex);fclose(stdout);return0;}Semaphore
  信号量(Semaphore)是维护0到指定最大值之间的同步对象。信号量状态在其计数大于0时是有信号,而其计数是0时是无信号的。信号量对象在控制上可以支持有限数量共享资源的访问。
  信号量的特点和用途可用下列几句话定义:如果当前资源的数量大于0,则信号量有效;如果当前资源数量是0,则信号量无效;系统决不允许当前资源的数量为负值;当前资源数量决不能大于最大资源数量。
  【创建信号量】HANDLEWINAPICreateSemaphore(LPSECURITYATTRIBUTESlpSemaphoreAttributes,信号量的安全属性LONGlInitialCount,开始时可供使用的资源数LONGlMaximumCount,最大资源数LPCWSTRlpName信号量的名称);
  【释放信号量】BOOLWINAPIReleaseSemaphore(HANDLEhSemaphore,要增加的信号量句柄LONGlReleaseCount,信号量的当前资源数增加lReleaseCountLPLONGlpPreviousCount增加前的数值返回);
  【打开信号量】HANDLEWINAPIOpenSemaphore(DWORDdwDesiredAccess,accessBOOLbInheritHandle,如果允许子进程继承句柄,则设为TRUELPCWSTRlpName指定要打开的对象的名字);
  【销毁信号量】BOOLWINAPICloseHandle(HANDLEhObject);
  【示例】includeiostreamincludecstdlibincludecstdioincludectimeincludewindows。hintsemaphorenum1;定义全局变量HANDLEhSemaphoreNULL;定义信号量句柄DWORDWINAPIThreadFunction(LPVOIDparam){intid(int)longresult0;while(semaphorenum100){WaitForSingleObject(hSemaphore,INFINITE);printf(threaddusesemaphorenum:d,id,semaphorenum);ReleaseSemaphore(hSemaphore,1,result);Sleep(1000);}returnNULL;}intmain(){HANDLEhThread〔5〕{NULL};intthread〔5〕{0};DWORDthreadid〔5〕{0};hSemaphoreCreateSemaphore(NULL,1,100,Lsema);for(inti0;i5;i){thread〔i〕i1;hThread〔i〕CreateThread(NULL,0,ThreadFunction,thread〔i〕,0,threadid〔i〕);}Sleep(1000);for(inti0;i5;i){WaitForSingleObject(hThread〔i〕,INFINITE);}CloseHandle(hSemaphore);return0;}Event
  事件(Event):是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaledortrue)或未激发状态(unsignalorfalse)。根据状态变迁方式的不同,事件可分为两类:手动设置:这种对象只可能用程序手动设置,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设置。
  【创建事件】HANDLEWINAPICreateEvent(LPSECURITYATTRIBUTESlpEventAttributes,BOOLbManualReset,BOOLbInitialState,LPCWSTRlpName);参数说明:lpEventAttributes安全配置相关参数,采用默认安全配置时传入NULLbManualReset传入TRUE时创建manualreset模式的事件对象,传入FALSE时创建autoreset模式的事件对象bInitialState传入TRUE时创建signaled状态,传入FALSE时创建nonsignaled状态的事件对象lpName用于命名事件对象。传递NULL时创建无名的事件对象
  当第二个参数传入TRUE时将创建manualreset模式的事件对象,此时即使WaitForSingleObject函数返回也不会回到nonsignaled状态。因此,在这种情况下,需要通过如下2个函数明确更改对象状态。
  【打开事件】HANDLEWINAPIOpenEvent(DWORDdwDesiredAccess,BOOLbInheritHandle,LPCSTRlpName);
  【复位事件】BOOLWINAPIResetEvent(HANDLEhEvent);
  【设置事件】BOOLWINAPISetEvent(HANDLEhEvent);
  传递事件对象句柄并希望改为nonsigned状态时,应调用ResetEvent函数。如果希望改为signaled状态,则可以调用SetEvent函数。
  【示例】includeiostreamincludecstdlibincludecstdioincludectimeincludewindows。hinteventnum1;定义全局变量HANDLEhEventNULL;定义事件句柄DWORDWINAPIThreadFunction(LPVOIDparam){intid(int)longresult0;while(eventnum100){WaitForSingleObject(hEvent,INFINITE);printf(threaddusesemaphorenum:d,id,eventnum);SetEvent(hEvent);Sleep(1000);}returnNULL;}intmain(){HANDLEhThread〔5〕{NULL};intthread〔5〕{0};DWORDthreadid〔5〕{0};hEventCreateEvent(NULL,FALSE,TRUE,Levent);for(inti0;i5;i){thread〔i〕i1;hThread〔i〕CreateThread(NULL,0,ThreadFunction,thread〔i〕,0,threadid〔i〕);}Sleep(1000);for(inti0;i5;i){WaitForSingleObject(hThread〔i〕,INFINITE);}CloseHandle(hEvent);return0;}
投诉 评论 转载

vivoX70pro开箱识别度满满的是高级旗舰的质感在当今消费者的购买决策中,手机的外观价值也成为重要的考虑因素。特别是对于选择高级旗舰产品的用户来说,外观的质感、识别度等是值得关注的地方。vivo旗下的Pro级旗舰产品,viv……华为智选哈尔斯智能水杯,智能功能贼多,生活更加美好结构篇华为智选智能水杯350ml白色(支持HUAWEIHiLink)实时显示水温饮水量电量,饮水预订管理,12小时保温保冷,抑菌材料,316医用级不锈钢内胆,IPX7级防……全屏实力的荣耀X20综合评测史上最窄边框的诚意之作在8月12日荣耀年度新品的发布会上,除了万众瞩目的高端机型Magic3系列之外,还有一款旨在打破传统边框界限的X系列新作荣耀X20。说起荣耀X系列,相信有现在依旧还有很多荣耀X……5款产品打造高颜值极简桌面办公环境清爽效率才高清爽整洁的桌面不光是看起来美观清爽,更能提高办公效率,让自己的心情更加愉悦。我自己就是一个喜欢极简风数码产品的人,身边的数码产品都是极简风格的,整体氛围和谐统一。这里我挑选了5……印度两少年从斯坦福辍学回国创业公司九个月估值达9亿美元由印度两名青少年创办的10分钟杂货配送服务初创公司Zepto在新一轮融资中筹集了2亿美元,公司估值达到9亿美元左右,距离他们创办这家公司仅过了9个月时间。Zepto在周一……全球最大!中国风力涡轮机有多强?巴西人美没有做到中国做到了我国风力涡轮机打破纪录!中国明阳智能能源公司推出全球最大风力涡轮机,中国的科技到底有多强?国外观察人士给出了高度评价和认可!近年来,随着中国的迅速崛起,在科技领域的成就也……天选2搭配RTX30系光追显卡真香华硕天选2游戏本配备有RTX30系光追显卡、11代酷睿高性能移动处理器以及高刷新率电竞屏,娱乐办公皆不错,是这个暑期不容错过的超值选择。目前在华硕京东自营官方旗舰店,酷睿……Windows线程同步的四种方式为什么要进行线程同步在多线程的程序中,很少有多个线程能在其生命期内进行完全独立的操作;通常情况是一些线程进行某些操作,而其他的线程必须对其操作后的结果进行了解。如果不采取……为什么现在还有很多人不签手机银行,宁可去银行网点排队?尽管当前非现金支付十分流行,微信支付宝给人们提供了不少方便,但是作为银行开发的手机银行APP,应该说是功能最齐全的APP。那为什么还有很多人不签手机银行,宁可去银行网点排队呢?……手机内存满了,没用的软件都卸载了,不管用,有什么好方法没有?感谢您的阅读!手机内存满了,没用的软件都卸载了,不管用有什么好方法呢?分享一点。很多人都说苹果手机非常的流畅,但是你不知道如果手机的内存不能满足我们使用,它依……图发现macOS钥匙串漏洞的18岁少年决定向苹果公布所有细节在没有获得苹果任何报酬的情况下,LinusHenze还是决定向苹果公司提交有关在macOS钥匙串(Keychain)安全软件中发现的严重BUG。之前他选择隐藏该BUG细节,以抗……颤乐APP互联网现场音乐平台,赋能演出市场,实现共赢根据《中国音乐产业发展报告》公开数据表示:2017年中国音乐产业总规模达3470。94亿元;2018年音乐演艺市场总体规模达3747。85亿元;2019年中国……
HUAWEI内网最新发布了一份452页网络协议手册,GitH低代码平台不计成本助力国内企业数字化转型,是炒作还是确有此事华为智能家万物联网,鸿蒙道生TMobile大规模客户数据泄露,黑客发帖大胆售卖规范自动续费服务资产缩水800亿,马斯克遭币圈反噬某大厂表示如适配鸿蒙,恐命门被人捏,华为可为所欲为带币一哥马斯克重启MX梦想系列?魅族新款旗舰将至,比魅族18更强硬汉再升级!OLIGHT武士WarriorX3战术手电体验原5月23日的vivoT2新品发布会调整为6月6日1900发今年第一季度中国智能手机市场OPPO排名榜首先抑后扬写树根的作文三人篮球亚洲杯中国男队大胜汤加资格赛轻松赢得开门红事业与公益同行这个全能艺人值得学习火的造句用火的造句大全创造纪录的太空之旅!神十三飞船成功发射1周年自闭症孩子母亲做你的李焕英,真心好累地方政府预算账本之谜:禁令重重缘何“砍掉”不多?剑王朝赵香妃的真实身份揭秘,赵香妃骊陵君是什么关系?房地产企业营改增后的财税问题研究厮守汾鮟萣的繁体字网名大全品牌与山头,该如何理性选择?辽宁第一潮人!郭艾伦见了都认输鞋带当裤腰带用他是第一人

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利