All posts by admin

browser caching control from server

.htaccess

ExpiresActive On
ExpiresByType text/html “access plus 1 seconds”
ExpiresByType image/gif “access plus 2 years”
ExpiresByType image/jpeg “access plus 2 years”
ExpiresByType image/png “access plus 2 years”
ExpiresByType text/css “access plus 2 years”
ExpiresByType text/javascript “access plus 2 years”
ExpiresByType application/x-javascript “access plus 2 years”
ExpiresByType image/ico “access plus 2 years”

ski ,bromont st bruno

st bruno

20 KM to south shore

Trail map

Vertical drop (134 m). Number of trails (15). Easy (5). Difficult (5). Very difficult (3). Extreme (2). Snow board facilities. Night time lighting (15). Snowmaking system (100 %). Iniski / Inisurf classes. Lifts (8). Triple  chairlifts (2). Quad  chairlifts (2). Surface lifts (4)

2013-10-25 0-21-24

bromont 80 km to south shore

trail map

 

2013-10-25 0-12-33

 

 

Ski Bromont  vertical drop 351m , longest run 1km

 

驾照笔试

交通标志


                               

A) 停牌在前面150米(500英尺)
B) 不平路在前面120米(400英尺)
C) 任何时间都必须停车
D) 当接近别的车辆时才停

C


                               

A) 靠安全岛的右面驶过
B) 路转右然后转左
C) 弯曲路在前
D) 在其他车辆右面驶过

A


                               

A) 停牌在前
B) 让有优先权者先行
C) 前面是路的尽头
D) 慢行的车辆在前

D


                               

A) 修路的标志–慢驶服从修路者旗的指导
B) 修路的标志代替修路者的旗
C) 限制路牌–减低速度
D) 此牌警告公路修理工程在前

D


                               

A) 你一定只可右转
B) 你不能左传
C) 隐蔽的十子路口在前
D) 你接近一安全岛

B


                               

A) 路湿时很滑
B) 不准右转
C) 不准左转
D) 你不能掉头(或U转)

D


                               

A) 交通灯在前
B) 停牌在前面150米(500英尺)
C) 不平路在前面120米(400英尺)
D) 火车路在前

A


                               

A) 目的地指示牌
B) 学校区域小心儿童玩耍
C) 省公园
D) 行人路牌

A


                               

A) 学校巴士过十子路口
B) 学校区斑马线的标志
C) 小心-学校巴士驶过
D) 限制路牌

D


                               

A) 工厂在前,慢驶
B) 凹凸路或不平坦的路
C) 修路地区
D) 桥或桥梁

B


                               

A) 游乐场的路牌
B) 你接近一条火车路
C) 你接近医院地区
D) 你接近行人斑马线

B


                               

A) 分叉路在前
B) 分叉路结束
C) 窄桥在前
D) 公路在修

A


                               

A) 此线只准右转
B) 此线准许各方向转弯包括左转
C) 从箭头的指示至角落,不准泊车
D) 特别警告危险

A


                               

A) 十字路口,不准驶入
B) 不准停车牌
C) 汽车驶向此角度,一定要停
D) 停牌所指示的方向不需要停

B


                               

A) 由此牌至下一路牌,最高时速五十公里
B) 乡村学校区内的时速
C) 每小时五十公里完
D) 前面时速每小时最高可达五十公里

D


                               

A) 学校区在前
B) 火车路在前
C) 你一定让有优先权者先行
D) 你有优先权

C


                               

红色圈的意思是:
A) 不准驶入此路
B) 不准驶入除非区内居民
C) 代表前面有一交通圈
D) 禁止路牌

D


                               

A) 隐蔽的十子路口在前
B) 弯曲路在前
C) 路湿时很滑
D) 窄路在前

B


                               

绿色圈的意思是:
A) 货车路线
B) 不准货车
C) 大货车的路线
D) 准许的路牌

D


                               

A) 游乐场的路牌
B) 儿童在住宅区玩耍
C) 学校区的路牌
D) 指示儿童的路牌

C


                               

A) 我正在右转
B) 我正在左转
C) 我正在慢下或停车
D) 我可以超越

A


                               

A) 靠右行驶
B) 靠左行驶
C) 不准驶入
D) 不准超越

C


                               

A) 弯曲路在前
B) 靠左
C) 危险,路的尽头
D) 危险,急弯

D


                               

A) 我正在转右
B) 我正在转左
C) 我正在慢驶或停车
D) 我正在停车

B


                               

A) 我正在转左
B) 我正在慢驶或停车
C) 我正在转右
D) 你可以超越

B


                               

A) 分叉路在前
B) 你正接近一条单程路
C) 隐蔽路口在前
D) 路面转窄

D


                               

A) 前面有安全检查
B) 警告斜坡在前
C) 路在前面五百尺终止
D) 不平路在前

B


                               

A) 弯曲路在前
B) 不平路在前
C) 前面湿时很滑
D) 前面不准超越

C


                               

A) 右线终止
B) 隐蔽的十子路口在前
C) 你正接近一个斜坡
D) 行人斑马线在前

A


                               

A) 窄路在前
B) 前面的路转左然后转右
C) 前面的路转右然后转左
D) 十字路口在前

C


                               

A) 停牌在前
B) 让有优先权者先行
C) 前面是路的尽头
D) 慢行的车辆在前面

A


                               

A) 分叉公路在前
B) 分叉公路完或接合
C) 窄桥在前
D) 公路在修理中

B


                               

A) 不可右转
B) 分叉公路完或接合
C) 窄桥在前
D) 红灯不可右转

D


                               

A) 右线终止
B) 隐蔽的十子路口在前
C) 你正接近一个斜坡
D) 不准超越

D


                               

A) 如果你保持在右线行驶,你可以驶出此公路
B) 在任何情形下, 你不能在右线行驶
C) 公路终止, 你一定要转右线行驶
D) 两边转左线

D


                               

A) 十字路口在前
B) 窄桥在前
C) 前方道路完
D) 道路在前分叉

B


                               

A) 窄路在前
B) 隐藏路在前
C) 火车路在前
D) 十字路口在前

D


                               

A) 前右边有货车出入口
B) 货车不可进入
C) 见到货车时要减速
D) 货车专线

A


                               

A) 轮椅或残疾人停泊
B) 弯曲路在前
C) 不准停泊
D) 不准站留

A


                               

A) 不可接近
B) 新婴儿在车上
C) 新驾驶者
D) 新车

C


                               

A) 小心驾驶
B) 与对路车分享道路
C) 路面湿时很滑
D) 不可停车

B


                               

A) 这条线是保留给专线车辆,如巴士,的士,脚踏车及
       车上有三名乘客以上在制定时间日期专用
B) 在制定时间及日期,巴士是不能在专线行驶
C) 在制定时间及日期,是不能停车的
D) 在制定时间及日期,是不准驶入的

A


                               

A) 留心动物,鹿有时横过
B) 动物园在前
C) 见到动物不能按喇叭
D) 鹿群欢迎的

A


                               

A) 学校区
B) 不平坦的路
C) 不准站或停在这处
D) 脚踏车不能行驶

C

 

交通常识

1 当你到达十字路口而看到黄色的闪灯时,你一定要:
1.停,如果你想转右
2.保持同样的速度行驶
3.停车,如果你想转左
4.慢驶,然后小心前进

2 当你在变线行车路上驾驶,听到紧急信号的车,法律上要求你怎样做?
1.加速,尽快离开
2.打灯号,让驾驶者超越
3.尽快驶向路的最右方停下
4.保持同一速度行驶

3 当需要车头灯时,在什么情况下开低灯?
1.与最接近你的车辆相距一公里(0.6哩)内
2.与最接近你的车辆相距150公尺(500呎)内
3.与最接近你的车辆相距300公尺(1000呎)内
4.这是为安全而设,并不是法律规定

4 当你驶近”停牌”时,你应:
1.慢驶,鸣笛然后前进
2.慢驶,当安全才继续前进
3.停车,鸣笛然后前进
4.停车,当安全才前进

5 除非有标志指明,不然在城市、市镇、乡村或发展区内最高的驾驶速度应是:
1.每小时30公里(20哩)
2.每小时50公里(30哩)
3.每小时40公里(25哩)
4.每小时60公里(35哩)

6 当亮红灯时,你想驶过十字路口,你一定要:
1.停车,让行人有优先权,然后小心前进
2.停车,当交通安全才前进
3.慢驶,交通安全才前进
4.停车,直至灯号转绿色,同时安全才前进

7 当驶入高速公路时,你应该:
1.停在加速线,看准有安全的位置才尽快驶入高速公路
2.加速达到高速公路的速度,然后驶入公路交通中
3.慢车,然后用直角方向驶入高速公路
4.慢驶,随时准备停下来应付公路的交通

8 在公路,驾驶者不准在其汽车所拖的露营车或拖船上载有:
1.枪械
2.容易燃烧原料
3.人(乘客)
4.家畜

9 在双程路上,你想转左之前,你应在什么位置?
1.靠近路的右手边
2.靠近路的左手边
3.尽量在最接近中线的右边行车路上
4.没有关系,只要打灯号便可

10 在十字路口亮绿灯时,以下谁最有优先权?
1.行人不守灯号过马路
2.行人遵守灯号过马路
3.正在转右的车辆
4.正在转左的车辆

11 在单程路上你想转左之前,你应在路的什么位置?
1.靠近路的右手边
2.靠近路的中线
3.靠近路的左手边
4.不成问题,只要你打讯号

12 当电车停下让乘客上落,当时没有安全岛,你想驶过电车时,法律上要你怎样做?
1.停在电车后面,然后前进
2.响号,同时小心驶过
3.由左边驶过,当交通安全
4.在电车后门2公尺(6呎)之后停车,让乘客上落,直至安全才驶过

13 在十字路口闪着红灯,表示:
1.慢驶,然后加倍小心驾驶
2.慢驶,如有需要,让左右迎面的车辆有优先权
3.灯号坏了,小心前进
4.停车,直至安全才前进

14 当红灯可以转右时,在未驶入十字路口前,法律上你应怎么做?
1.慢驶,小心前进
2.停车,然后侧侧地进入交通中
3.停车,打灯号,当不阻碍别地车辆及行人才转弯
4.慢驶,打讯号及转弯

15 当你想转右时,你应驶在路的哪一条线?
1.靠近路的左边
2.靠近路的右边
3.靠近路的中线
4.不成问题,打灯便可

16 当到达十字路口,绿灯刚转黄灯,你应怎样做?
1.停车,如果停车是危险的,前进要加倍小心
2.加速,并尽快驶过十字路口
3.继续驶过十字路口,不用慢驶或停下来
4.响号,并警告行人和别的驾驶者,使他们知道你不会停车

17 某人的驾驶执照被吊销后他
1.在非常紧急时,可以驾驶
2.返工及放工时才准驾驶
3.在有车牌的人陪同下才可驾驶
4.在任何情况下都不准驾驶

18 在安大略省,是有安全带法例
1.对
2.不对
3.只是在公路上驾驶时
4.只是在市区内驾驶时

19 当两架车在大约同一时间驶到没有标志的十字路口,哪一架车有优先权?
1.从左方驶来的车辆
2.从右方驶来的车辆
3.两者都不是
4.驶得较快的车辆

20 在安全的情况下,可从别的车辆右方超越:
1.任何街道及公路都准许
2.如果可能在路旁驶过是准许的
3.无论在什么情况下都不准许
4.是准许的,当街道及公路有两条或以上同一方向的行车线

21 法律上,在什么时候需要把车头灯开着?
1.在日落和日出时
2.在黄昏及黎明之间和在任何时间150公尺(500呎)内看不清时
3.在日落前半小时,在日出后半小时及任何时间在150公尺(500呎)内看不清事物时
4.没有特别时间规定

22 驾驶者是否要负责车上乘客扣上安全带呢?
1.只是乘客在十六岁以上
2.只是乘客在五岁至十六岁
3.只是乘客在前面的座位
4.只是乘客在十八岁以上

23 当需要开车头灯时,驾驶者必要用低灯,当跟在别的车后面
1. 30公尺(100呎)内
2. 60公尺(200呎)内
3. 120公尺(400呎)内
4. 只是当接近其他车辆时

24 当驶近”让牌”时,在法例上你应怎样做?
1.慢下,如有需要时停下及让路于有优先权者先行
2.停,然后慢驶入交通中
3.停,然后快速驶入交通中
4.加速,并挤迫入交通中

25 酒精在人体血液中占什么份量,使你成为危险驾驶者及有罪?
1. 0.03%
2. 0.05%
3. 0.08%
4. 1.0%

26 在十字路口,亮红灯并有绿色箭头表示:
1.停,先等候绿灯,然后向绿色箭头的方向转
2.小心向着箭头的方向转,让路于有优先权的车辆及行人
3.停车,然后前进
4.绿色箭头只是给行人的讯号

27 一定要报警的交通意外是当有人受伤或损失超过
1.一百元
2.一百五十元
3.二百元
4.一千元

28 在十字路口,转左及转右都准许时,绿色闪灯表示:
1.路上安全,你可转左
2.路上安全,你可转右
3.路上安全,你可直驶
4.你可做任何以上的

29 如果交通灯转了,而行人仍然在过马路,以下谁有优先权
1.驾驶者正在转弯
2.行人
3.驾驶者从右面驶来
4.驾驶者从左面驶来

30 如果你被控醉酒行车,第一次会被罚停牌多久?
1.一个月
2.三个月
3.六个月
4.一年

31 在车上装有蓝色闪灯是表示:
1.车内装有爆炸品
2.铲雪的车辆
3.救伤车
4.有紧急事的警车

32 如果你置身于交通意外,而当时有人受伤,你一定要:
1.立即报告意外于最近的省警察或当地警察
2.在四十八小时内报告意外于最近的省警察或当地警察
3.只是报告意外向你的保险公司
4.只是报告意外事件给交通部

33 在离开城市,镇或乡村的高速公路同一方向行驶,除超越外,跟在商业汽车后面应保持什么距离?
1. 30公尺(100呎)
2. 60公尺(200呎)
3. 120公尺(400呎)
4. 150公尺(500呎)

34 持有驾驶执照而需要转姓名或地址,他需要在什么时间内通知交通部?
1.六天之内
2.十五天之内
3.三十天之内
4.在换新牌前任何时间都可

35 如果你置身在一件交通意外,而一定要报警,在什么时间内,你要报告给最近你的省警察或当地警察?
1.立刻
2.在二十四小时之内
3.在四十八小时之内
4.在七十二小时内

36 当货车在高速公路上不能开动时,照明器或反光器一定要放在货车的前面或后面多远呢?
1. 15公尺(50呎)
2. 30公尺(100呎)
3. 40公尺(200呎)
4. 90公尺(300呎)

37 以下什么情形下”u”转是危险和不合法的:
1.在弯路或在斜坡,视力从两方向150公尺(500呎)内看不清楚时
2.在火车路上或火车路30公尺(100呎)之内
3.在桥、高架公路或隧道中150公尺(500呎)内,视力受阻碍时
4.以上所有的情形都包括在内

38 驾驶者被停牌,而被控再次驾驶,他应受什么责罚?
1.罚款五百元或入狱六个月或两样都罚
2.将汽车扣留三个月
3.再加多六个月不准驾驶的权利
4.以上任何一点或全部

39 当驶近火车路时,看到有电动式的机械讯号或有人拿着旗号警告有火车来时,你应:
1.停车在距离路轨最少1.5公尺(5呎)
2.加速尽快驶过火车路
3.停车在距离路轨最少5公尺(15呎)
4.慢驶,小心前进

40 如果车主没有买汽车保险,他有什么保障?
1.一万元保险赔偿
2.二万元保险赔偿
3.三万五千元保险赔偿
4.全无保险赔偿

41 在什么情形下,驾驶执照会被取消?
1.没有去重考
2.持有改过的执照
3.重考而不合格
4.以上任何情形或全部都是

42 警察有权要求车主拿出什么文件:
1.如汽车有买保险——保险纸
2.汽车车主证
3.如只是汽车驾驶者——有效驾驶执照
4.以上任何一项都是

43 在什么情形下可将驾驶执照借给他人?
1.永远不能
2.可以借给正在学车者
3.只可作表明身份用
4.在紧急时

44 当你驶近十字路口,正亮着红色交通灯,而警察打手势指挥你通过,你应:
1.等候绿灯
2.服从警察的指挥,立即通过
3.让警察知道当时亮着红灯
4.停下来,确定他要你通过

45 驾驶者犯上开快车,比限制时速超过五十公里(三十哩)或以上时,法庭会将怎样处罚呢?
1.停牌六个月
2.停牌三十天
3.扣留汽车六个月
4.驾驶者入狱六个月

46 当你接近十字路口时,发觉十字路口前面交通很挤迫,你应:
1.贴着前面的车辆行驶
2.慢慢驶入十字路口,直至前面交通畅通后才前进
3.停在十字路口之前,等待前面交通畅通后才前进
4.响号警告前面车辆前进

47 一辆”校车”闪红灯停在中间没有栏杆或障碍物的高速公路中,无论你是迎面而来或从后面超越,法律要求你:
1.没有关系,只要你响号
2.停车,直至校车前进或红灯已不再闪
3.等待接近的车辆驶过
4.减低速度,同时小心驶过

48 驾驶人可能需要被接见问话或重考驾驶技术:
1.当驾驶过失而被记下的分数达到九点
2.当驾驶过失而被记下的分数达到三点
3.当驾驶过失而被记下的分数达到六点
4.当驾驶过失而被记下的分数达到十五点

49当驾驶过失达到九点时,被接见问话后,交通部可能暂停驾驶人执照:
1.当驾驶人不能提出充分的理由反对停用执照
2.当驾驶人没有五年的驾驶经验
3.如驾驶人的执照不是作商业用途
4.驾驶过失除非达到十五点交通部时不能暂停执照的

50 当驾驶人的过失记录达到十五点或以上时,执照将受暂停:
1.自动停牌,从退回执照起停牌三十天
2.由交通部再审查
3.如执照不是作商业用途
4.三个月

51 当过失点达到十五分时,牌照要吊销三十天恢复驾驶后的分数,将会
1.减到七分
2.减到零分
3.减到五分
4.以上全不是

52 卖汽车给别人,卖车者应该:
1.在卖车后六日内通知交通部及改车主姓名
2.和买车者到换牌处登记更换新车主姓名
3.如汽车没有”安全合格证”应交还车牌及车证给换牌处,而用卖车者的名下取得”汽车未合格证”
4.以上所有情形都是

53 你应保持一种速度行车,无论在任何情况下,你也能:
1.在90公尺(300呎)内停车
2.在60公尺(200呎)内停车
3.在一个安全距离内停车
4.在150公尺(500呎)内停车

54 不能随时换线除非先:
1.发出正确灯号及肯定安全才能转线
2.减慢速度及打出正确灯号
3.只看倒后镜
4.响喇叭及望后面

55 法律规定泊车距离救火喉多远才是合法的:
1. 3公尺(10呎)
2. 4.5公尺(15呎)
3. 1.5公尺(5呎)
4. 6公尺(20呎)

56 大多数汽车滑胎的原因是:
1.车胎汽不够
2.车胎太多汽
3.路上有雪或冰
4.驾驶速度太快

57 在什么时候可用泊车灯?
1.什么时候都可以用
2.在泊车时用
3.在大雾中驾驶时用
4.在光线充足的街道上驾驶时用

58 在湿滑或结冰的路上快速停车的最好方法是:
1.在脚制上一踏一放的方法,直至车辆完全停下来
2.把脚离开脚制,使车自动停下
3.大力踏在脚制上,预防车辆滑行
4.像你平时一样方法踏脚制

59 在大雾中行驶,你应用:
1.泊车灯
2.低灯
3.泊车灯及高灯
4.高灯

60 当你泊车在向下的斜坡在你离开车之前,你应:
1.扭直前胎与路边平行
2.扭前胎向左,并拉紧手掣
3.只是拉紧手掣
4.扭前胎向右,并拉紧手掣

61 当你知道另一辆车准备驶过或超越时,你应:
1.驶向路的右边,让他超越
2.加速使他不能超越
3.打灯号暗示他不要超越
4.驶向左边,阻止他超越

62 当你右边车胎驶入路边泥地,哪一个是最好的方法让车驶回路面:
1.大力把方向盘扭去左边
2.踏脚制并大力把方向盘扭去左边
3.脚离开油门,让车辆慢下来时才驶回路面
4.踏脚制以减慢速度

63 当你驾驶每小时50公里(30哩)应该和前面车辆最少保持多远才安全:
1.七个车位的距离
2.三个车位的距离
3.一个车位的距离
4.五个车位的距离

64 除非有特别标志,负责在城市镇、乡村或发展区以外的公路,最高的驾驶速度是:
1.每小时100公里(60哩)
2.每小时80公里(50哩)
3.每小时60公里(40哩)
4.每小时50公里(30哩)

65 当你把车驶出停车位前,你应:
1.看交通情形,打灯号及立即驶离路边
2.响号然后慢慢从路边驶出
3.看清楚交通情形,打灯号,当安全的时候才从路边驶出
4.打灯号,然后驶出路边

66 当汽车驶下斜坡时,最安全的方法是:
1.用低波行驶及利用机器帮助煞掣
2.扭熄汽车机器
3.用中波行驶
4.解脱汽车离合器,使车溜下

67 夜间在快速公路行驶时,你必须用低灯,当你:
1.接近十字路口
2.遇到迎面有车来或跟在别的车辆后时
3.当其他车辆用低灯
4.遇到迎面车辆的车头灯,使你看不清楚

68 在夜间以最高限制速度行驶比日间更危险,因为:
1.一些非法驾驶者只用泊车灯行驶
2.在夜间,你不能看得前面很远
3.在夜间,路面更用以湿滑
4.你的反应在夜间会较慢

69 以下哪一种手势讯号是表示慢驶或停车?
1.手臂伸出向上
2.手臂伸直向窗外
3.手臂伸出向下
4.转圆圈的动作

70 在夜间行驶,当你遇到迎面车辆车灯很强烈耀眼,使你看不清楚,最安全的方法是:
1.迅速的将眼睛一张一合
2.看着迎面车辆的车头灯
3.把车灯转用高灯
4.把视线稍为望向路的右手边

71 当车辆停下来让行人过斑马线时,你应:
1.从左面超越停下的车
2.响号指挥停车的驾驶者向前行驶
3.从右面超越停下的车
4.不能超越任何停下来让行人过马路的车辆

72 路的中间有断续的线是代表:
1.不能超越
2.可以超越,当交通安全时
3.随时可以超越
4.在日间才可以超越

73 除非你打算扒过及超越另一辆车,或想转左,否则你应:
1.驾驶在路的中间
2.时时靠路的右面行驶
3.在公路的沙地上行驶
4.时时靠路的左边行驶

74 当你决定”U转”与否之前,你首先应查看:
1.交通规则
2.有没有树,救火喉,或路边灯柱
3.你的汽车转弯的范围内
4.路边的高度

75 路的中间,有一实线,有一虚线,而你靠近实线,实线的意思是:
1.扒头或超越是不安全的
2.没有车辆时才可以超越
3.扒头及超越是安全的
4.随时都可以超越

76 由私家路驶入公路之前,驾驶者应:
1.响号并小心前进
2.尽快驶入或横过公路
3.打手势及取优先权先行
4.让所有驶近公路的车辆有优先权

77 当驾驶时你其中一个车胎突然爆胎,你应:
1.集中注意在方向盘
2.脚离开油门使车速减慢
3.使汽车停下在路旁
4.以上全部都是

78 当电车停站让乘客上落,当时是一个安全岛,在法律上你应怎样做:
1.小心驶过
2.停在安全岛后最小2公尺
3.响号小心驶过
4.在电车的左面驶过

79 如果你驶近十字路口而交通灯坏了,你应:
1.让右面交通先行
2.停,直到无车时才驶过
3.处理像四面停牌一样
4.减慢小心驶过

80 当校巴停下,上落乘客而你驶过会怎样:
1.监禁一年
2.扣六分及罚款高达一千元
3.警告及罚款一百元
4.重考路试

81 由定罪那天起,过失点停留在你驾驶记录多久:
1. 1年
2. 2年
3. 3年
4. 5年

82 当你的汽车滑胎时,首先怎样应付:(例如车尾滑向右边)
1.把方向盘转向相反滑的方向
2.把方向盘转直走
3.大力刹停汽车
4.把方向盘转向滑车的方向

83 在驾驶时,如果你失控,车胎驶出路旁,你应:
1.紧握方向盘
2.脚离开油门使车速放慢,避免重踏脚制
3.当车得到控制后驶回车路上
4.以上全部都是

84 在初两年第一阶段(G1)及第二阶段(G2)驾驶者,如你的过失点在九分或以上,你会停牌多久:
1.60天
2.30天
3.一年
4.15天

85 407高速公路是:
1.安省最长公路
2.是一条新公路
3.是一条快速收费公路
4.快速公路通去美国

86 第一阶段(G1)及第二阶段(G2)驾驶者,在驾驶时体内酒精量是零,如果被捉,除行事法外,还要停牌多久?:
1. 30天
2. 60天
3. 90天
4. 1年

87 如果你在驾驶时手提电话响,你应怎样做:
1.在驾驶中尽快简短地谈话
2.用电话留言,当车停下时再查口信
3.如果邻近没有警察就可以谈话
4.驾驶时是不能用手提电话的

88 第一阶段(G1)驾驶者,你一定要有一个G牌或以上陪同驾驶,他的驾驶经验在几年以上:
1. 3年
2. 4年
3. 8年
4. 6年

89 如果你驾驶时因使用手提电话发生意外:
1.你的保险费增加
2.你会被控诉,危险驾驶及扣六分
3.你要停牌一年
4.你要重考路试

90 如果你是第二阶段(G2)驾驶者,你要维持酒精含量在:
1.百分之0.08
2.百分之0.05
3.百分之0.03
4.百分之零

91 雪胎什么时候用最好:
1.在夏天驾驶
2.在四季都可路
3.在冬天使用
4.在春天及秋天用

92 在公路交通法规被停牌,而你是第一次被捉驾驶,刑罚是:
1.罚款500元
2.罚款1000到5000元
3.坐监6个月
4.以上全部都是

93 警察有权截查可疑醉酒驾驶者,如你拒绝用酒精测试器,你的车牌会立刻被吊销到:
1. 30天
2. 1年
3. 60天
4. 90天

94 在两年内第一阶段(G1)及第二阶段(G2)的驾驶者,过失分在9分或以上时,在停牌60天后过失点减到:
1. 6分
2. 4分
3. 0分
4. 2分

95 如果你的脚制失控:
1.在脚制上用一踏一放方法
2.逐渐地拉实手制
3.手按着手制的按钮上
4.以上全部都是

96 第一阶段(G1)的驾驶者,你一定不能喝酒驾驶,而陪同的G牌陪同者酒精要少过:
1.零度酒精
2.百分之0.05
3.百分之0.08
4.百分之0.03

97 如果你是”犯刑事法”停牌,而被捉驾驶,你的汽车会被扣压多久?:
1. 1年
2. 6个月
3. 45天
4. 30天

98 如果有一辆车紧跟随你后面,你应怎样呢?:
1.如果安全时,转去其他行车线
2.轻微地减慢与前面车辆增远距离
3.驶近路旁让紧跟随车超越
4.以上全部都是

99 如果你想超越一部摩托车,你应:
1.在超越前响号
2.在超越前将你的高灯开亮
3.方法像超越其他车辆
4.用摩托车的一半行车线

100 为什么在换线时要查看盲点:
1.这个运动是对你的颈部好
2.无论怎样调校,你的镜子总有些盲点
3.要看看谁是驾驶者
4.以上全部都是

101 你如果发生交通意外,在什么情况下一定要报警?:
1.损失小过六百元
2.损失超过一千元
3.如有人受伤或死亡
4.以上2及3都是对的

102 如果你是青年驾驶者,刚在6个月内考取G2牌照,在深夜12时到早上5时,你可乘载多少乘客:
1. 3个在19岁或以下的乘客
2. 不能有乘客在19岁或以下
3. 1个在19岁或以下的乘客
4. 2个在19岁或以下的乘客

103 如果你是青年驾驶者,考取G2牌照超过6个月后,在没有考得G牌或未满20岁时,你可乘载多少乘客在深夜12时到早上5时:
1. 3个在19岁或以下的乘客
2. 不能有乘客在19岁或以下
3. 1个在19岁或以下的乘客
4. 2个在19岁或以下的乘客

104 青年驾驶者有些例外,如果有一个____年G牌驾驶者坐在前排或其他青年乘客都是他直属家人:
1. 2年
2. 3年
3. 4年
4. 5年

105 在晚间驾驶,如车速快过你的车头灯所照到的是危险,因为:
1.你驶车太快
2.你的车头灯太亮
3.你看到时,想停也停不下来
4.这对汽车电池是不好的

 

Message Length

4.4 Message Length

The transfer-length of a message is the length of the message-body as   it appears in the message; that is, after any transfer-codings have   been applied. When a message-body is included with a message, the   transfer-length of that body is determined by one of the following   (in order of precedence):

1.Any response message which “MUST NOT” include a message-body (such     as the 1xx, 204, and 304 responses and any response to a HEAD     request) is always terminated by the first empty line after the     header fields, regardless of the entity-header fields present in     the message.

2.If a Transfer-Encoding header field (section 14.41) is present and     has any value other than “identity”, then the transfer-length is     defined by use of the “chunked” transfer-coding (section 3.6),     unless the message is terminated by closing the connection.

3.If a Content-Length header field (section 14.13) is present, its     decimal value in OCTETs represents both the entity-length and the     transfer-length. The Content-Length header field MUST NOT be sent     if these two lengths are different (i.e., if a Transfer-Encoding

     header field is present). If a message is received with both a
     Transfer-Encoding header field and a Content-Length header field,
     the latter MUST be ignored.

4.If the message uses the media type “multipart/byteranges”, and the     transfer-length is not otherwise specified, then this self-     delimiting media type defines the transfer-length. This media type     MUST NOT be used unless the sender knows that the recipient can parse     it; the presence in a request of a Range header with multiple byte-     range specifiers from a 1.1     client implies that the client can parse multipart/byteranges responses.

       A range header might be forwarded by a 1.0 proxy that does not
       understand multipart/byteranges; in this case the server MUST
       delimit the message using methods defined in items 1,3 or 5 of
       this section.

5.By the server closing the connection. (Closing the connection     cannot be used to indicate the end of a request body, since that     would leave no possibility for the server to send back a response.)

For compatibility with HTTP/1.0 applications, HTTP/1.1 requests   containing a message-body MUST include a valid Content-Length header   field unless the server is known to be HTTP/1.1 compliant. If a   request contains a message-body and a Content-Length is not given,   the server SHOULD respond with 400 (bad request) if it cannot   determine the length of the message, or with 411 (length required) if   it wishes to insist on receiving a valid Content-Length.

All HTTP/1.1 applications that receive entities MUST accept the   “chunked” transfer-coding (section 3.6), thus allowing this mechanism   to be used for messages when the message length cannot be determined   in advance.

Messages MUST NOT include both a Content-Length header field and a   non-identity transfer-coding. If the message does include a non-   identity transfer-coding, the Content-Length MUST be ignored.

When a Content-Length is given in a message where a message-body is   allowed, its field value MUST exactly match the number of OCTETs in   the message-body. HTTP/1.1 user agents MUST notify the user when an   invalid length is received and detected.

review IOCP

A:

Create IO_HANDLE

Creat thread to process GetQueuedCompletionStatus

A:: AllocateContext for reference back when IOCP return

A::Write  WSASend  SetReferenc_WriteComplete

A::Read   WSARecv  SetReference_ReadComplete

A::OnWriteComplete

A::OnReadComplete

Managing Memory-Mapped Files

executed. Instead, much of the file input/output (I/O) is cached to improve general system performance. You can override this behavior and force the system to perform disk transactions immediately by using the memory-mapped file function FlushViewOfFile explained later.

What Do Memory-Mapped Files Have to Offer?

One advantage to using MMF I/O is that the system performs all data transfers for it in 4K pages of data. Internally all pages of memory are managed by the virtual-memory manager (VMM). It decides when a page should be paged to disk, which pages are to be freed for use by other applications, and how many pages each application can have out of the entire allotment of physical memory. Since the VMM performs all disk I/O in the same manner—reading or writing memory one page at a time—it has been optimized to make it as fast as possible. Limiting the disk read and write instructions to sequences of 4K pages means that several smaller reads or writes are effectively cached into one larger operation, reducing the number of times the hard disk read/write head moves. Reading and writing pages of memory at a time is sometimes referred to as paging and is common to virtual-memory management operating systems.

Another advantage to using MMF I/O is that all of the actual I/O interaction now occurs in RAM in the form of standard memory addressing. Meanwhile, disk paging occurs periodically in the background, transparent to the application. While no gain in performance is observed when using MMFs for simply reading a file into RAM, other disk transactions can benefit immensely. Say, for example, an application implements a flat-file database file structure, where the database consists of hundreds of sequential records. Accessing a record within the file is simply a matter of determining the record’s location (a byte offset within the file) and reading the data from the file. Then, for every update, the record must be written to the file in order to save the change. For larger records, it may be advantageous to read only part of the record into memory at a time as needed. Unfortunately, though, each time a new part of the record is needed, another file read is required. The MMF approach works a little differently. When the record is first accessed, the entire 4K page(s) of memory containing the record is read into memory. All subsequent accesses to that record deal directly with the page(s) of memory in RAM. No disk I/O is required or enforced until the file is later closed or flushed.

Note

During normal system paging operations, memory-mapped files can be updated periodically. If the system needs a page of memory that is occupied by a page representing a memory-mapped file, it may free the page for use by another application. If the page was dirty at the time it was needed, the act of writing the data to disk will automatically update the file at that time. (A dirty page is a page of data that has been written to, but not saved to, disk; for more information on types of virtual-memory pages, see “The Virtual-Memory Manager in Windows NT” on the Developer Network CD.)

The flat-file database application example is useful in pointing out another advantage of using memory-mapped files. MMFs provide a mechanism to map portions of a file into memory as needed. This means that applications now have a way of getting to a small segment of data in an extremely large file without having to read the entire file into memory first. Using the above example of a large flat-file database, consider a database file housing 1,000,000 records of 125 bytes each. The file size necessary to store this database would be 1,000,000 * 125 = 125,000,000 bytes. To read a file that large would require an extremely large amount of memory. With MMFs, the entire file can be opened (but at this point no memory is required for reading the file) and a view (portion) of the file can be mapped to a range of addresses. Then, as mentioned above, each page in the view is read into memory only when addresses within the page are accessed.

How Are They Implemented?

Since Windows NT is a page-based virtual-memory system, memory-mapped files represent little more than an extension of an existing, internal memory management component. Essentially all applications in Windows NT are represented in their entirety by one or more files on disk and a subset of those files resident in random access memory (RAM) at any given time. For example, each application has an executable file that represents pages of executable code and resources for the application. These pages are swapped into and out of RAM, as they are needed, by the operating system. When a page of memory is no longer needed, the operating system relinquishes control over the page on behalf of the application that owns it and frees it for use by another. When that page becomes needed again, it is re-read from the executable file on disk. This is called backing the memory with a file, in this case, the executable file. Similarly, when a process starts, pages of memory are used to store static and dynamic data for that application. Once committed, these pages are backed by the system pagefile, similar to the way the executable file is used to back the pages of code. Figure 2 is a graphical representation of how pages of code and data are backed on the hard disk.

ms810613.maname02(en-us,MSDN.10).gif

Figure 2. Memory used to represent pages of code in processes for Windows NT are backed directly by the application’s executable module while memory used for pages of data are backed by the system pagefile.

Treating both code and data in the same manner paves the way for propagating this functionality to a level where applications can use it, too—which is what Windows does through memory-mapped files.

Shared Memory in Windows NT

Both code and data are treated the same way in Windows NT—both are represented by pages of memory and both have their pages backed by a file on disk. The only real difference is the file by which they are backed—code by the executable image and data by the system pagefile. Because of this, memory-mapped files are also able to provide a mechanism for sharing data between processes. By extending the memory-mapped file capability to include portions of the system pagefile, applications are able to share data that is backed by the pagefile. Shown in Figure 3, each application simply maps a view of the same portion of the pagefile, making the same pages of memory available to each application.

ms810613.maname03(en-us,MSDN.10).gif

Figure 3. Processes share memory by mapping independent views of a common region in the system pagefile.

Windows NT’s tight security system prevents processes from directly sharing information among each other, but MMFs provide a mechanism that works with the security system. In order for one process to share data with another via MMFs, each process must have common access to the file. This is achieved by giving the MMF object a name that both processes use to open the file.

Internally, a shared section of the pagefile translates into pages of memory that are addressable by more than one process. To do this, Windows NT uses an internal resource called a prototype page-table entry (PPTE). PPTEs enable more than one process to address the same physical page of memory. A PPTE is a system resource, so their availability and security is controlled by the system alone. This way processes can share data and still exist on a secure operating system. Figure 4 indicates how PPTEs are used in Windows NT’s virtual addressing scheme.

ms810613.maname04(en-us,MSDN.10).gif

Figure 4. Prototype page-table entries are the mechanism that permits pages of memory to be shared among processes.

One of the best ways to use an MMF for sharing data is to use it in a DLL (dynamic-link library). The PortTool application serves as a useful illustration. PortTool uses a DLL to provide its porting functionality and relies on the main application for the user interface. The reason for this is simple: Other applications can then also use the DLL functionality. That is, other editors that are programmable can import the porting functionality. Because it is entirely feasible for PortTool to be running while another editor that imports the PortTool DLL is also running, it is best to economize system resources as much as possible between the applications. PortTool does this by using an MMF for sharing the porting information with both processes. Otherwise, both applications would be required to load their own set of porting information while running at the same time, a waste of system resources. The PortTool code demonstrates sharing memory via an MMF in a DLL.

Using Memory-Mapped File Functions

Memory-mapped file functions can be thought of as second cousins to the virtual-memory management functions in Windows. Like the virtual-memory functions, these functions directly affect a process’s address space and pages of physical memory. No overhead is required to manage the file views, other than the basic virtual-memory management that exists for all processes. These functions deal in reserved pages of memory and committed addresses in a process. The entire set of memory-mapped file functions are:

  • CreateFileMapping
  • OpenFileMapping
  • MapViewOfFile
  • MapViewOfFileEx
  • UnmapViewOfFile
  • FlushViewOfFile
  • CloseHandle

Each of these functions is individually discussed below, along with code examples that demonstrate their use.

Creating a File Mapping

To use a memory-mapped file, you start by creating a memory-mapped file object. The act of creating an MMF object has very little impact on system resources. It does not affect your process’s address space, and no virtual memory is allocated for the object (other than for the internal resources that are necessary in representing the object). One exception, however, is that, if the MMF object represents shared memory, an adequate portion of the system pagefile is reserved for use by the MMF during the creation of the object.

The CreateFileMapping function is used to create the file-mapping object as demonstrated in the example listed below, a portion of PMEM.C, the source module from the ProcessWalker sample application.

case IDM_MMFCREATENEW:
    {
    char    szTmpFile[256];

    /* Create temporary file for mapping. */
    GetTempPath (256, szTmpFile);
    GetTempFileName (szTmpFile,
                     "PW",
                     0,
                     MMFiles[wParam-IDM_MMFCREATE].szMMFile);

    /* If file created, continue to map file. */
    if ((MMFiles[wParam-IDM_MMFCREATE].hFile =
           CreateFile (MMFiles[wParam-IDM_MMFCREATE].szMMFile,
                       GENERIC_WRITE | GENERIC_READ,
                       FILE_SHARE_WRITE,
                       NULL,
                       CREATE_ALWAYS,
                       FILE_ATTRIBUTE_TEMPORARY,
                       NULL)) != (HANDLE)INVALID_HANDLE_VALUE)
        goto MAP_FILE;
    }
    break;

case IDM_MMFCREATEEXIST:
    {
    char   szFilePath[MAX_PATH];
    OFSTRUCT   of;

    /* Get existing filename for mapfile. */
    *szFilePath = 0;
    if (!GetFileName (hWnd, szFilePath, "*"))
        break;

    /* If file opened, continue to map file. */
    if ((MMFiles[wParam-IDM_MMFCREATE].hFile =
            (HANDLE)OpenFile (szFilePath, &of, OF_READWRITE)) !=
                (HANDLE)HFILE_ERROR)
        goto MAP_FILE;
    }
    break;

case IDM_MMFCREATE:
    /* Associate shared memory file handle value. */
    MMFiles[wParam-IDM_MMFCREATE].hFile = (HANDLE)0xffffffff;

MAP_FILE:
    /* Create 20MB file mapping. */
    if (!(MMFiles[wParam-IDM_MMFCREATE].hMMFile =
        CreateFileMapping (MMFiles[wParam-IDM_MMFCREATE].hFile,
                           NULL,
                           PAGE_READWRITE,
                           0,
                           0x01400000,
                           NULL)))
        {
        ReportError (hWnd);
        if (MMFiles[wParam-IDM_MMFCREATE].hFile)
            {
            CloseHandle (MMFiles[wParam-IDM_MMFCREATE].hFile);
            MMFiles[wParam-IDM_MMFCREATE].hFile = NULL;
            }
        }
    break; /* from IDM_MMFCREATE */

In the sample code above, three cases are demonstrated. They represent creating a memory-mapped file by first creating a temporary disk file, creating a memory-mapped file from an existing file, and creating a memory-mapped file out of part of the system pagefile. In case IDM_MMFCREATENEW, a temporary file is created first, before the memory-mapped file. For case IDM_MMFCREATEEXIST, the File Open dialog is used to retrieve a filename, and that file is then opened before the memory-mapped file is created. In the third case, IDM_MMFCREATE, the memory-mapped file is created either using the system pagefile or using one of the standard files created in the two earlier cases.

Notice that the CreateFileMapping function need only be called once for all three different cases. The first parameter to the CreateFileMapping function, hFile, is used to supply the handle to the file that is to be memory-mapped. If the system pagefile is to be used, the value 0xFFFFFFFF must be specified instead. In the above examples, a structure is used to represent both the standard file and memory-mapped file information. In the example above, the hMMFile field in the structure MMFiles[wParam-IDM_MMFCREATE] is either 0xFFFFFFFF (its default value), or it is the value of the file handle retrieved in either of the earlier cases.

In all three cases, the memory-mapped file is specified to be 20 MB (0x01400000) in size, regardless of the size of any files created or opened for mapping. The fourth and fifth parameters, dwMaximumSizeHigh and dwMaximumSizeLow, are used to indicate the size of the file mapping. If these parameters indicate a specific size for the memory-mapped file when memory mapping a file other than the pagefile, the file on disk is fitted to this new size—whether larger or smaller makes no difference. As an alternative, when memory mapping a file on disk, you can set the size parameters to 0. In this case, the memory-mapped file will be the same size as the original disk file. When mapping a section of the pagefile, you must specify the size of the memory-mapped file.

The second parameter to the CreateFileMapping function, lpsa, is used to supply a pointer to a SECURITY_ATTRIBUTES structure. Since memory-mapped files are an object, they have the same security attributes that can be applied to every other object. A NULL value indicates that no security attributes are relevant to your use of the memory-mapped file.

The third parameter, fdwProtect, is used to indicate the type of protection to place on the entire memory-mapped file. You can use this parameter to protect the memory-mapped file from writes by specifying PAGE_READONLY or to permit read and write access with PAGE_READWRITE.

One other parameter of interest is the lpszMapName parameter, which can be used to give the MMF object a name. In order to open a handle to an existing file-mapping object, the object must be named. All that is required of the name is a simple string that is not already being used to identify another object in the system.

Obtaining a File-Mapping Object Handle

In order to map a view of a memory-mapped file, all you need is a valid handle to the MMF object. You can obtain a valid handle in one of several ways: by creating the object as described above, by opening the object with the OpenFileMapping function, by inheriting the object handle, or by duplicating the handle.

Opening a memory-mapped file object

To open a file-mapping object, the object must have been given a name during the creation of the object. A name uniquely identifies the object to this and other processes that wish to share the MMF object. The following portion of code from PORT.C shows how to open a file-mapping object by name.

/* Load name for file-mapping object. */
LoadString (hDLL, IDS_MAPFILENAME, szMapFileName, MAX_PATH);

/* After first process initializes, port data. */
if ((hMMFile = OpenFileMapping (FILE_MAP_WRITE, 
                                FALSE, 
                                szMapFileName)))
    /* Exit now since initialization was already performed by 
       another process. */
     return TRUE;

/* Retrieve path and file for ini file. */
if (!GetIniFile (hDLL, szIniFilePath))
    return FALSE;

/* Test for ini file existence and get length of file. */
if ((int)(hFile = (HANDLE)OpenFile (szIniFilePath, 
                                    &of, 
                                    OF_READ)) == -1)
    return FALSE;

else
    {
    nFileSize = GetFileSize (hFile, NULL);
    CloseHandle (hFile);
    }

/* Allocate a segment of the swap file for shared memory 2*Size 
   of ini file. */
if (!(hMMFile = CreateFileMapping ((HANDLE)0xFFFFFFFF,
                                    NULL,
                                    PAGE_READWRITE,
                                    0,
                                    nFileSize * 2,
                                    szMapFileName)))
    return FALSE;

The OpenFileMapping function requires only three arguments, the most important of these being the name of the object. As shown in the example, the name is simply a unique string. If the string is not unique to the system, the MMF object will not be created. Once the object exists, however, the name is guaranteed for the life of the object.

Also, note in the above example that the MMF object is opened first, possibly before the object has been created. This logic relies on the fact that, if the object does not already exist, the OpenFileMapping function will fail. This is useful in a DLL where the DLL’s initialization code is called repeatedly, once for every process that attaches to it.

The sample from PORT.C above occurs in the DLL’s initialization code that is called every time a DLL gets attached to another process. The first time it is called, the OpenFileMapping function fails because the object does not already exist. The logic, then, continues execution until it reaches the CreateFileMapping function, and it is there that the object is first created. Immediately after initially creating the object, the PortTool code initializes the data in the file mapping by writing porting-specific information to the memory-mapped file. To do this, the memory-mapped file is created with PAGE_READWRITE protection. All subsequent calls to the DLL’s initialization function result in the OpenFileMapping function successfully returning a valid object handle. This way the DLL does not need to keep track of which process is the first to attach to the DLL.

Note that for every process that attaches to the DLL, the object name is retrieved from the same source—a string from the DLL’s resource string table. Since the DLL is able to retrieve the object name from its own resource string table, the name is global to all processes, yet no process is actually aware of the name used. The DLL is able to effectively encapsulate this functionality while at the same time providing the benefit of shared memory to each process that attaches to the DLL.

The PortTool example presents a useful context for sharing memory. Yet, keep in mind that any file on disk could have been used in the same way. If an application were to implement some database services to several other applications, it could set up memory-mapped files using basic disk files, instead of the pagefile, and share that information in the same way. And as the first code listing illustrates, a temporary file could be used to share data instead of the pagefile.

Inheriting and duplicating memory-mapped file object handles

Ordinarily, for two processes to share a memory-mapped file, they must both be able to identify it by name. An exception to this is child processes, which can inherit their parent’s handles. Most objects in Windows can be explicitly targeted for inheritance or not. (Some objects are not inheritable, such as GDI object handles.) When creating an MMF object, a Boolean field in the optional SECURITY_ATTRIBUTES structure can be used to designate whether the handle is to be inheritable or not. If the MMF object handle is designated as inheritable, any child processes of the process that created the object can access the object through the same handle as their parent.

Literally, this means the child process can access the object by supplying the same handle value as the parent. Communicating that handle to the child process is another concern. The child process is still another process after all, having its own address space, so the handle variable itself is not transferable. Either some interprocess communication (IPC) mechanism or the command line can be used to communicate handle values to child processes.

Further, the DuplicateHandle function is provided to offer more control as to when handles can be inherited and not. This function can be used to create a duplicate handle of the original and can be used to change the inheritance state of the handle. An application can invoke this function to change an MMF object handle state to inheritable before passing the handle along to a child process, or it can do the opposite—it can take an inheritable handle and preserve it from being inherited.

Viewing Part of a Memory-Mapped File

Once obtained, the handle to the memory-mapped file object is used to map views of the file to your process’s address space. Views can be mapped and unmapped at will while the MMF object exists. When a view of the file is mapped, system resources are finally allocated. A contiguous range of addresses, large enough to span the size of the file view, are now committed in your process’s address space. Yet, even though the addresses have been committed for the file view, physical pages of memory are still only committed on a demand basis when using the memory. So, the only way to allocate a page of physical memory for a committed page of addresses in your memory-mapped file view is to generate a page fault for that page. This is done automatically the first time you read or write to any address in the page of memory.

To map a view of a memory-mapped file, use either the MapViewOfFile or the MapViewOfFileEx function. With both of these functions, a handle to a memory-mapped file object is a required parameter. The following example shows how the PortTool sample application implements this function.

/* Map a view of this file for writing. */
lpMMFile = (char *)MapViewOfFile (hMMFile, 
                                  FILE_MAP_WRITE, 
                                  0, 
                                  0, 
                                  0);

In this example, the entire file is mapped, so the final three parameters are less meaningful. The first parameter specifies the file-mapping object handle. The second parameter indicates the access mode for the view of the file. This can be FILE_MAP_READ, FILE_MAP_WRITE, or FILE_MAP_ALL_ACCESS, provided the protection on the file-mapping object permits it. If the object is created with PAGE_READWRITE protection, all of these access types are available. If, on the other hand, the file is created with PAGE_READONLY protection, the only access type available is FILE_MAP_READ. This allows the object creator control over how the object can be viewed.

The second and third parameters are used to indicate the low and high halves, respectively, of a 64-bit offset into the memory-mapped file. This offset from the start of the memory-mapped file is where the view is to begin. The final parameter indicates how much of the file is to be viewed. This parameter can be set to 0 to indicate that the entire file is to be mapped. In that case, the 64-bit offset value is ignored.

The function returns a pointer to the location in the process’s address space where the file view has been mapped. This is an arbitrary location in your process, depending on where the contiguous range of addresses are available. If you want to map the file view to a specific set of addresses in your process, the MapViewOfFileEx function provides this capability. This function simply adds an additional parameter, lpvBase, to indicate the location in your process to map the view. The return value to MapViewOfFileEx is the same value as lpvBase if the function is successful; otherwise, it is NULL. Similarly, for MapViewOfFile the return value is NULL if the function fails.

Multiple views of the same file-mapping object can coexist and overlap each other as shown in Figure 5.

ms810613.maname05(en-us,MSDN.10).gif

Figure 5. Memory-mapped file objects permit multiple, overlapped views of the file from one or more processes at the same time.

Notice that multiple views of a memory-mapped file can overlap, regardless of what process maps them. In a single process with overlapping views, you simply end up with two or more virtual addresses in a process that refer to the same location in physical memory. So, it’s possible to have several PTEs referencing the same page frame. Remember, each page of a shared memory-mapped file is represented by only one physical page of memory. To view that page of memory, a process needs a page directory entry and page-table entry to reference the page frame.

There are two ways in which needing only one physical page of memory for a shared page benefits applications in the system. First, there is an obvious savings of resources because both processes share both the physical page of memory and the page of hard disk storage used to back the memory-mapped file. Second, there is only one set of data, so all views are always coherent with one another. This means that changes made to a page in the memory-mapped file via one process’s view are automatically reflected in a common view of the memory-mapped file in another process. Essentially, Windows NT is not required to do any special bookkeeping to ensure the integrity of data to both applications.

Unmapping a View of a Memory-Mapped File

Once a view of the memory-mapped file has been mapped, the view can be unmapped at any time by calling the UnmapViewOfFile function. As you can see below, there is nothing tricky about this function. Simply supply the one parameter that indicates the base address, where the view of the file begins in your process

/* Load tokens for APIS section. */
LoadString (hDLL, IDS_PORTAPIS, szSection, MAX_PATH);
if (!LoadSection (szIniFilePath, 
                  szSection, 
                  PT_APIS, 
                  &nOffset, 
                  lpMMFile))
        {
        /* Clean up memory-mapped file. */
        UnmapViewOfFile (lpMMFile);
        CloseHandle (hMMFile);
        return FALSE;
        }

As mentioned above, you can have multiple views of the same memory-mapped file, and they can overlap. But what about mapping two identical views of the same memory-mapped file? After learning how to unmap a view of a file, you could come to the conclusion that it would not be possible to have two identical views in a single process because their base address would be the same, and you wouldn’t be able to distinguish between them. This is not true. Remember that the base address returned by either the MapViewOfFile or the MapViewOfFileEx function is not the base address of the file view. Rather, it is the base address in your process where the view begins. So mapping two identical views of the same memory-mapped file will produce two views having different base addresses, but nonetheless identical views of the same portion of the memory-mapped file.

The point of this little exercise is to emphasize that every view of a single memory-mapped file object is always mapped to a unique range of addresses in the process. The base address will be different for each view. For that reason the base address of a mapped view is all that is required to unmap the view.

Flushing Views of Files

An important feature for memory-mapped files is the ability to write any changes to disk immediately if necessary. This feature is provided through the FlushViewOfFile function. Changes made to a memory-mapped file through a view of the file, other than the system pagefile, are automatically written to disk when the view is unmapped or when the file-mapping object is deleted. Yet, if an application needs to force the changes to be written immediately, FlushViewOfFile can be used for that purpose.

  /* Force changes to disk immediately. */
FlushViewOfFile (lpMMFile, nMMFileSize);

The example listed above flushes an entire file view to disk. In doing so, the system only writes the dirty pages to disk. Since the Windows NT virtual-memory manager automatically tracks changes made to pages, it is a simple matter for it to enumerate all dirty pages in a range of addresses, writing them to disk. The range of addresses is formed by taking the base address of the file view supplied by the first parameter to the FlushViewOfFile function as the starting point and extending to the size supplied by the second parameter, cbFlush. The only requirement is that the range be within the bounds of a single file view.

Releasing a Memory-Mapped File

Like most other objects, a memory-mapped file object is closed by calling the CloseHandle function. It is not necessary to unmap all views of the memory-mapped file before closing the object. As mentioned above, dirty pages are written to disk before the object is freed. To close a memory-mapped file, call the CloseHandle function, which supplies the memory-mapped file object handle for the function parameter.

/* Close memory-mapped file. */
CloseHandle (hMMFile);

It is worth noting that closing a memory-mapped file does nothing more than free the object. If the memory-mapped file represents a file on disk, the file must still be closed using standard file I/O functions. Also, if you create a temporary file explicitly for use as a memory-mapped file as in the initial ProcessWalker example, you are responsible for removing the temporary file yourself. To illustrate what the entire cleanup process may look like, consider the following example from the ProcessWalker sample application.

case IDM_MMFFREE:
case IDM_MMFFREENEW:
case IDM_MMFFREEEXIST:
    {
    HCURSOR    hOldCursor;
    OFSTRUCT   of;

    /* Put hourglass cursor up. */
    hOldCursor = (HCURSOR)SetClassLong (hWnd, GCL_HCURSOR, 0);
    SetCursor (LoadCursor (0, IDC_WAIT));

    /* Release memory-mapped file and associated file if any. */
    CloseHandle (MMFiles[wParam-IDM_MMFFREE].hMMFile);
    MMFiles[wParam-IDM_MMFFREE].hMMFile = NULL;

    if (MMFiles[wParam-IDM_MMFFREE].hFile)
        {
        CloseHandle (MMFiles[wParam-IDM_MMFFREE].hFile);
        MMFiles[wParam-IDM_MMFFREE].hFile = NULL;
        }

    /* If temporary file, delete here. */
    if (wParam == IDM_MMFFREENEW)
        {
        OpenFile (MMFiles[wParam-IDM_MMFFREE].szMMFile, 
                  &of, 
                  OF_DELETE);
        *(MMFiles[wParam-IDM_MMFFREE].szMMFile) = 0;
        }

    /* Replace wait cursor with old cursor. */
    SetClassLong (hWnd, GCL_HCURSOR, (LONG)hOldCursor);
    SetCursor (hOldCursor);
    }
    break;

In this example, the memory-mapped file can be one of three types: the system pagefile, a temporary file, or an existing file on disk. If the file is the system pagefile, the memory-mapped file object is simply closed, and no additional cleanup is necessary. If the memory-mapped file is mapped from an existing file, that file is closed right after closing the memory-mapped file. If the memory-mapped file is a mapping of a temporary file, it is no longer needed and is deleted using standard file I/O immediately after closing the temporary file handle, which cannot occur until after closing the memory-mapped file object handle.

Conclusion

Memory-mapped files provide unique methods for managing memory in the Windows application programming interface. They permit an application to map its virtual address space directly to a file on disk. Once a file has been memory-mapped, accessing its content is reduced to dereferencing a pointer.

A memory-mapped file can also be mapped by more than one application simultaneously. This represents the only mechanism for two or more processes to directly share data in Windows NT. With memory-mapped files, processes can map a common file or portion of a file to unique locations in their own address space. This technique preserves the integrity of private address spaces for all processes in Windows NT.

Memory-mapped files are also useful for manipulating large files. Since creating a memory mapping file consumes few physical resources, extremely large files can be opened by a process and have little impact on the system. Then, smaller portions of the file called “views” can be mapped into the process’s address space just before performing I/O.

There are many techniques for managing memory in applications for Windows. Whether you need the benefits of memory sharing or simply wish to manage virtual memory backed by a file on disk, memory-mapped file functions offer the support you need.

Interprocess Synchronization

Interprocess Synchronization

            8 out of 18 rated this helpful – Rate this topic

Multiple processes can have handles to the same event, mutex, semaphore, or timer object, so these objects can be used to accomplish interprocess synchronization. The process that creates an object can use the handle returned by the creation function (CreateEventCreateMutexCreateSemaphore, or  CreateWaitableTimer). Other processes can open a handle to the object by using its name, or through inheritance or duplication. For more information, see the following topics: