C/C 临界量 - 范文中心

C/C 临界量

12/20

1.CRITICAL_SECTION:不能锁定资源,只是同步代码

简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。

也正由于CRITICAL_SECTION是这样发挥作用的,所以,必须把每一个线程中访问共享资源的语句都放在EnterCritialSection和LeaveCriticalSection之间。这是初学者很容易忽略的地方。

CRITICAL_SECTION临界区的使用在线程同步中应该算是比较简单,在使用临界区的时候要注意,每一个共享资源就有一个CRITICAL_SECTION,如果要一次访问多个共享变量,各个线程要保证访问的顺序一致,如果不一致,很可能发生死锁。

1: InitializeCriticalSection(&g_cs_listview); 2: InitializeCriticalSectionAndSpinCount(&g_cs_listview); 3: DeleteCriticalSection(&g_cs_listview); 4: TryEnterCriticalSection(&g_cs_listview); 5: EnterCriticalSection(&g_cs_listview); 6: LeaveCriticalSection(&g_cs_listview);

注意:假如多个线程都在等待同一个critical section,究竟哪个线程会先获得它的所有权是不一定的,cirtical section在这方面没有保证.

2.Semaphore信号量:

Semaphore对象用来控制对资源的并发访问数。内部有个计数器,当值>=0设置了信号,==0清除信号。每次调用wait函数计数器都减1。调用ReleaseSemaphore时将计数器设置为lREleaseCount的指定的值。

// 创建信号量,且设置为1表示每次只能有一个线程访问;

// 如果创建失败表示该"semaphore_test"标示符在别的进程中创建,可用OpenSemaphore来打开信号量

// CreateSemaphore(为安全属性,Semaphore的初始值,最大值,对象的名字)

HANDLE hSe = CreateSemaphore(NULL, 1, 1, "semaphore_test");

// 释放本进程的信号量

// ReleaseSemaphore(句柄,要增加的数值,用于返回之前的计算值)

ReleaseSemaphore(hSe, 1, NULL);

// 等待一个对象是否可用;

ret = WaitForSingleObject(hSe, 1000);

case WAIT_OBJECT_0: // 如果是WaitForSingleObject第一个对象就是等待的句柄

case WAIT_TIMEOUT:  // 超时

1: #include "stdafx.h" 2: #include 3: #include 4: using namespace std; 5:  6: const int MAX_RUNNUM = 3; //最多运行实例个数 7: void PrintInfo() 8: { 9: char c; 10: cout > c; 15: if (c == 's') 16: { 17: break; 18: } 19: Sleep(10); 20: } 21: } 22: int main(int argc, char* argv[]) 23: { 24: HANDLE hSe = CreateSemaphore(NULL, MAX_RUNNUM, MAX_RUNNUM, "semaphore_test"); 25: DWORD ret = 0; 26: if (hSe == NULL) 27: { 28: cout

3.Mutex-互斥体

mutex互斥体的意思,当一个线程持有一个Mutex时,其它线程申请持有同一个Mutex会被阻塞在一个队列中,当互斥体释放后队列中的第一个线程首先获得使用权。

//创建一个互斥体

//CreateMutex(安全描述符, Mutex的持有者设置为调用线程, Mutex的名字)

//如果创建失败表示该名称的mutex标示符在别的进程中创建,可用OpenMutex来打开信号量

HANDLE hmutex = CreateMutex(NULL, false, NULL);

//销毁互斥体

CloseHandle(hmutex);

// 等待一个对象是否可用;

ret = WaitForSingleObject(hmutex, 1000);

case WAIT_OBJECT_0: // 如果是WaitForSingleObject第一个对象就是等待的句柄

case WAIT_TIMEOUT:  // 超时

1: //互斥体通常用于多进程之间的同步问题 2:  3: //程序运行单个实例: 4: #include "stdafx.h" 5: #include 6: #include 7: #include 8: using namespace std; 9:  10: //当输入s或者c时候结束程序 11: void PrintInfo(HANDLE& h, char t) 12: { 13: char c; 14: while (1) 15: { 16: cin >> c; 17: if (c == t) 18: { 19: ReleaseMutex(h); 20: CloseHandle(h); 21: break; 22: } 23: Sleep(100); 24: } 25: } 26: int main(int argc, char* argv[]) 27: { 28: //创建mutex,当已经程序发现已经有这个mutex时候,就相当于openmutex 29: HANDLE hHandle = CreateMutex(NULL, FALSE, "mutex_test"); 30: if (GetLastError() == ERROR_ALREADY_EXISTS) 31: { 32: cout

4.Event事件

创建一个事件:

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

第1个参数:安全属性大多默认为null

第2个参数:是否必须手工复位到无信号状态,false=线程结束就自动设置无信号

第3个参数:默认是否有信号;true有信号,false无信号

第4个参数:对象名称,大多为null

释放一个事件:

CloseHandle(hEvent);

设置一个事件有信号:

setEvent(hEvent);   //变成有信号状态

pluseEvent(hEvent); //一个脉冲:从无信号变成有信号再变成无信号

复位一个Event对象

ResetEvent(hEvent)

等待一个或多个事件有信号:

WaitForSingleObject(handle, INFINITE/*等待时间*/);

参数handle:可以(Event,Mutex,Process,Thread,Semaphore)等等; thread的join就是等thread实现的

参数INFINITE:是等待超时时间,INFINITE是死等

WaitForMultipleObjects(nCount, handle_array, false, INFINITE/*等待时间*/);

参数nCount:是监测event的个数

参数handle_array:是event数组

参数false:表示有一个信号就返回,true是等待所有事件都有信号才返回

参数INFINITE:是等待超时时间,INFINITE是死等

wait…返回值:

WAIT_OBJECT_0:表示第一个事件

WAIT_TIMEOUT:超时

WAIT_ABANDONED:

1: /*简单示例,一个线程不停读取用户输入并放入message列表, 2: 另一个线程模拟将message发送出去,如果没有消息,则发送线程处于阻塞状态等待, 3: 一旦有消息录入,输入线程将event置位,发送线程即被激活并逐个发送消息。*/ 4: #include "stdafx.h" 5: #include 6: #include 7: #include 8: #include 9: #include 10: using namespace std; 11:  12: #ifdef _UNICODE 13: typedef wstring tstring; 14: #define tcout wcout 15: #define tcin wcin 16: #else 17: typedef string tstring; 18: #define tcout cout 19: #define tcin cin 20: #endif /* _UNICODE */ 21:  22: typedef list StringList; 23:  24: HANDLE hMutex = NULL; 25: HANDLE hEvent = NULL; 26: HANDLE hSendThread = NULL; 27: StringList messages; 28:  29: bool isRunning; 30:  31: DWORD WINAPI SendThreadProc(LPVOID lpThreadParameter) 32: { 33: DWORD dw; 34: while(isRunning) 35: { 36: dw = WaitForSingleObject(hEvent, INFINITE); 37: if(dw != WAIT_OBJECT_0) 38: { 39: tcout > s; 78: if(s == _T("quit")) 79: { 80: isRunning = true; 81: break; 82: } 83:  84: DWORD dw = WaitForSingleObject(hMutex, INFINITE); 85: if(WAIT_OBJECT_0 != dw && WAIT_ABANDONED != dw) 86: { 87: tcout


相关内容

  • 如何评估海外上游项目的经济性
    如何评估海外上游项目的经济性? 与国内投资相比,海外石油勘探开发投资项目最主要的特征是市场环境不同,风险大.在所有的市场经营风险中,原油价格.投资水平以及产量是影响海外投资项目决策时机.投资项目回报和投资收益的重要因素.文章选取海外重点战略 ...
  • 近临界下HZSM-5催化的甲苯歧化反应
    第$$卷第(期 "!!#年"月燃*料*化*学*学*报!"#$%&'"()#*'+,*-./0$1&%23*4,%"'"516"'7$$8"7() ...
  • 超(超)临界循环流化床直流锅炉技术的发展
    第31卷第1期2010年1月中图分类号:TK229.5+4 文献标志码:A 电力建设 ElectricPowerConstruction 文章编号:1000-7229(2010)01-0001-06 Vol.31,No.1 2010·1·J ...
  • 20**年届临界生培养计划 Microsoft Word 文档
    红寺堡区第一中学2015届高三临界生培养计划 为了完成红寺堡区教育局下达给我校2014届高考指标任务,充分挖掘一本.二本临界生的学习潜力,对其进行有效培养,全面提高高考升学质量,确保高考奋斗目标的达成,实现学校领导提出的突破重点本科100人 ...
  • 超临界N2发泡技术
    超临界N2发泡技术 聚合物微发泡材料的制备过程可分为3个阶段,首先是将高浓度的非反应性气体(主要是二氧化碳或氮气)溶解到聚合物中,并形成聚合物/气体的单相溶液;然后,通过改变温度或压力等条件使体系处于热力学的不稳定状态,此时气体在溶液中的溶 ...
  • 班级高考总结分析
    高2015级9班高考成绩分析及总结 陈丽娟 一.班级情况简介:高2015及9班是由64名应届生1名插班生和4名补习生构成的大家庭. 整体上没有特别拔尖的优生, 临界生人数较多. 班风淳朴良好, 学风浓厚,绝大多数同学有吃苦耐劳顽强拼搏的精神 ...
  • 知网论文免费查重入口
    知网论文免费查重入口 近来要写个论文,需要下载一些参考文献,但是在中国知网,万方,维普等文献检索网站上只能查看论文摘要,无法下载全文,怎么办呢,于是就开始了百度论文免费全文下载方法的艰苦历程,终于有所收获,找到了一些方法,但是这些方法大部分 ...
  • CO2临界状态观测及PVT关系测试
    实验报告 课程名称: 化工专业实验1 指导老师: 李勇 成绩:__________________ 实验名称: CO2临界状态观测及PVT关系测试 实验类型:___________同组学生姓名: 一.实验目的和要求(必填) 二.实验内容和原 ...
  • 超临界干燥制备木材SiO2气凝胶复合材料及其纳米结构
    第33卷第3期2005年5月东 北 林 业 大 学 学 报 JOURNAL OF NORTHE AST F OREST RY UN I V ERSI TY Vol . 33No . 3 M ay . 2005 超临界干燥制备木材-Si O ...
  • 型钢混凝土临界保护层厚度研究
    第32卷第3期 山 2006年2月文章编号:100926825(2006)0320073203 SHANXI ARCHITECTURE 西建 32No.3筑 Vol. Feb. 2006 ・73・ 型钢混凝土临界保护层厚度研究 贺广零 卢晋 ...