﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-魔のkyo的工作室-随笔分类-Programming</title><link>http://www.cnitblog.com/luckydmz/category/2293.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 22 Feb 2021 19:18:22 GMT</lastBuildDate><pubDate>Mon, 22 Feb 2021 19:18:22 GMT</pubDate><ttl>60</ttl><item><title>Vue.js前端跨域请求代理设置方法</title><link>http://www.cnitblog.com/luckydmz/archive/2021/02/02/92410.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 02 Feb 2021 06:59:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2021/02/02/92410.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92410.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2021/02/02/92410.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92410.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92410.html</trackback:ping><description><![CDATA[开发环境下通过 <span style="background-color: yellow;">config/index.js</span> 配置代理<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;see&nbsp;http://vuejs-templates.github.io/webpack&nbsp;for&nbsp;documentation.</span><span style="color: #008000; "><br />
</span><span style="color: #0000FF; ">var</span>&nbsp;path&nbsp;=&nbsp;require('path')<br />
<br />
module.exports&nbsp;=&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;build:&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env:&nbsp;require('./prod.env'),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index:&nbsp;path.resolve(__dirname,&nbsp;'../dist/index.html'),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assetsRoot:&nbsp;path.resolve(__dirname,&nbsp;'../dist'),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assetsSubDirectory:&nbsp;'static',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assetsPublicPath:&nbsp;'/view/',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;productionSourceMap:&nbsp;<span style="color: #0000FF; ">true</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Gzip&nbsp;off&nbsp;by&nbsp;default&nbsp;as&nbsp;many&nbsp;popular&nbsp;static&nbsp;hosts&nbsp;such&nbsp;as</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Surge&nbsp;or&nbsp;Netlify&nbsp;already&nbsp;gzip&nbsp;all&nbsp;static&nbsp;assets&nbsp;for&nbsp;you.</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Before&nbsp;setting&nbsp;to&nbsp;`true`,&nbsp;make&nbsp;sure&nbsp;to:</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;npm&nbsp;install&nbsp;--save-dev&nbsp;compression-webpack-plugin</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;productionGzip:&nbsp;<span style="color: #0000FF; ">false</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;productionGzipExtensions:&nbsp;['js',&nbsp;'css'],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Run&nbsp;the&nbsp;build&nbsp;command&nbsp;with&nbsp;an&nbsp;extra&nbsp;argument&nbsp;to</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;View&nbsp;the&nbsp;bundle&nbsp;analyzer&nbsp;report&nbsp;after&nbsp;build&nbsp;finishes:</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;`npm&nbsp;run&nbsp;build&nbsp;--report`</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Set&nbsp;to&nbsp;`true`&nbsp;or&nbsp;`false`&nbsp;to&nbsp;always&nbsp;turn&nbsp;it&nbsp;on&nbsp;or&nbsp;off</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bundleAnalyzerReport:&nbsp;process.env.npm_config_report<br />
&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;dev:&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env:&nbsp;require('./dev.env'),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port:&nbsp;8080,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;autoOpenBrowser:&nbsp;<span style="color: #0000FF; ">true</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assetsSubDirectory:&nbsp;'static',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assetsPublicPath:&nbsp;'/',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxyTable:&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'/api':&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target:&nbsp;"http://backend-server:30101",&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;测试环境下配置端口转发</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;changeOrigin:&nbsp;<span style="color: #0000FF; ">true</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pathRewrite:&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"^/api":&nbsp;"",&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;重写路径，去掉前缀api</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;CSS&nbsp;Sourcemaps&nbsp;off&nbsp;by&nbsp;default&nbsp;because&nbsp;relative&nbsp;paths&nbsp;are&nbsp;"buggy"</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;with&nbsp;this&nbsp;option,&nbsp;according&nbsp;to&nbsp;the&nbsp;CSS-Loader&nbsp;README</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;(https://github.com/webpack/css-loader#sourcemaps)</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;In&nbsp;our&nbsp;experience,&nbsp;they&nbsp;generally&nbsp;work&nbsp;as&nbsp;expected,</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;just&nbsp;be&nbsp;aware&nbsp;of&nbsp;this&nbsp;issue&nbsp;when&nbsp;enabling&nbsp;this&nbsp;option.</span><span style="color: #008000; "><br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cssSourceMap:&nbsp;<span style="color: #0000FF; ">false</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</div>
<br /><br /><div>生产环境下通过前端所在服务器上的Nginx配置代理在 <br /><span style="background-color: yellow;">/etc/nginx/sites-enabled/default</span><br />中添加 location ^~/api/ 对应的块</div><div><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->server&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<img src="http://www.cnitblog.com/Images/dot.gif" alt="" /><img src="http://www.cnitblog.com/Images/dot.gif" alt="" /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;location&nbsp;/&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;First&nbsp;attempt&nbsp;to&nbsp;serve&nbsp;request&nbsp;as&nbsp;file,&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;as&nbsp;directory,&nbsp;then&nbsp;fall&nbsp;back&nbsp;to&nbsp;displaying&nbsp;a&nbsp;404.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try_files&nbsp;$uri&nbsp;$uri/&nbsp;=404;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;location&nbsp;^~/api/&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header&nbsp;Host&nbsp;$host;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header&nbsp;&nbsp;X-Real-IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$remote_addr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header&nbsp;&nbsp;X-Forwarded-For&nbsp;&nbsp;$proxy_add_x_forwarded_for;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header&nbsp;X-NginX-Proxy&nbsp;<span style="color: #0000FF; ">true</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rewrite&nbsp;^/api/(.*)$&nbsp;/$1&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_pass&nbsp;http:<span style="color: #008000; ">//</span><span style="color: #008000; ">backend-server:30101/;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<img src="http://www.cnitblog.com/Images/dot.gif" alt="" /><img src="http://www.cnitblog.com/Images/dot.gif" alt="" /><br />}</div><br /><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;">检验配置文件是否正确</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;">nginx -t</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;"></div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;">重启（重新读取配置）</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;">nginx -s reload</div><div yne-bulb-block="paragraph" style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;">或 serivice nginx restart</div><br /><br />当我们在前端通过axios请求地址 /api/Token 时，就会被转发到 http://backend-server:30101/Token</div><img src ="http://www.cnitblog.com/luckydmz/aggbug/92410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2021-02-02 14:59 <a href="http://www.cnitblog.com/luckydmz/archive/2021/02/02/92410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python实现滚动数组，Python特殊方法的使用，Python运算符重载</title><link>http://www.cnitblog.com/luckydmz/archive/2020/09/07/92340.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 07 Sep 2020 07:48:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2020/09/07/92340.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92340.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2020/09/07/92340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92340.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92340.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">class</span>&nbsp;RollArray:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Iterator:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self,&nbsp;subject):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.subject&nbsp;=&nbsp;subject<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.start&nbsp;=&nbsp;self.subject.idx<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.i&nbsp;=&nbsp;0<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__next__</span>(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;self.i&nbsp;&lt;&nbsp;self.subject.capability:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.start&nbsp;+&nbsp;self.i&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.subject:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;=&nbsp;self.subject[self.start&nbsp;+&nbsp;self.i]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.i&nbsp;+=&nbsp;1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;o<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.i&nbsp;+=&nbsp;1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">raise</span>&nbsp;StopIteration()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self,&nbsp;capability,&nbsp;items=[]):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.data&nbsp;=&nbsp;[None]&nbsp;*&nbsp;capability<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.used&nbsp;=&nbsp;[False]&nbsp;*&nbsp;capability<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.idx&nbsp;=&nbsp;0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.capability&nbsp;=&nbsp;capability<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;e&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;items:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.append(e)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;append(self,&nbsp;obj):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.data[self.idx]&nbsp;=&nbsp;obj<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.used[self.idx]&nbsp;=&nbsp;True<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.idx&nbsp;=&nbsp;(self.idx&nbsp;+&nbsp;1)&nbsp;%&nbsp;10<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;重载&nbsp;for&nbsp;e&nbsp;in&nbsp;x:</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__iter__</span>(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;RollArray.Iterator(self)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;重载&nbsp;[]&nbsp;const</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__getitem__</span>(self,&nbsp;i):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.used[i%self.capability]:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;self.data[i%self.capability]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">raise</span>&nbsp;IndexError()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;重载&nbsp;[]</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__setitem__</span>(self,&nbsp;i,&nbsp;v):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.data[i%self.capability]&nbsp;=&nbsp;v<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.used[i%self.capability]&nbsp;=&nbsp;True<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;v<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;重载&nbsp;del&nbsp;x[]</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__delitem__</span>(self,&nbsp;i):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.used[i%self.capability]&nbsp;=&nbsp;False<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;重载&nbsp;if&nbsp;e&nbsp;in&nbsp;x:</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__contains__</span>(self,&nbsp;i):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;self.used[i%self.capability]<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;tolist(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l&nbsp;=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;e&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l.append(e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;l<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__repr__</span>(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;f<span style="color: #800000; ">"</span><span style="color: #800000; ">{self.__class__.__name__}({self.capability},&nbsp;items={self.tolist()})</span><span style="color: #800000; ">"</span><br /><br /><br /><span style="color: #0000FF; ">if</span>&nbsp;<span style="color: #800080; ">__name__</span>&nbsp;==&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">__main__</span><span style="color: #800000; ">'</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;arr&nbsp;=&nbsp;RollArray(10,&nbsp;range(5))<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">del</span>&nbsp;arr[3]<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(arr)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(5,&nbsp;11):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr.append(i)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(arr)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;arr[11]&nbsp;=&nbsp;11<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(arr)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;e&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;arr:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(e)</div><img src ="http://www.cnitblog.com/luckydmz/aggbug/92340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2020-09-07 15:48 <a href="http://www.cnitblog.com/luckydmz/archive/2020/09/07/92340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python中监视线程卡死并自动崩溃退出 WatchDog</title><link>http://www.cnitblog.com/luckydmz/archive/2020/03/17/92113.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 17 Mar 2020 07:32:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2020/03/17/92113.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92113.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2020/03/17/92113.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92113.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92113.html</trackback:ping><description><![CDATA[监视主线程卡死，发现时进行处理，例如保错再主动崩溃退出，这样再结合监视崩溃自动重启就可以在卡死时实现自动重启。<br /><br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">import</span>&nbsp;threading<br /><span style="color: #0000FF; ">import</span>&nbsp;traceback<br /><span style="color: #0000FF; ">import</span>&nbsp;time<br /><span style="color: #0000FF; ">import</span>&nbsp;sys<br /><span style="color: #0000FF; ">import</span>&nbsp;os<br /><span style="color: #0000FF; ">from</span>&nbsp;functools&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;wraps<br /><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;from&nbsp;.logger&nbsp;import&nbsp;logger</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">class</span>&nbsp;WatchDog(threading.Thread):<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self,&nbsp;timeout=10,&nbsp;echo=False):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(WatchDog,&nbsp;self).<span style="color: #800080; ">__init__</span>()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.timeout&nbsp;=&nbsp;timeout<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.echo&nbsp;=&nbsp;echo<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.last_kicked_ts&nbsp;=&nbsp;time.time()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.lock&nbsp;=&nbsp;threading.Lock()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.thread_id&nbsp;=&nbsp;threading.currentThread().ident<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.terminated&nbsp;=&nbsp;False<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.setDaemon(True)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.start()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;terminate(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.terminated&nbsp;=&nbsp;True<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.join(self.timeout)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;kick(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.last_kicked_ts&nbsp;=&nbsp;time.time()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.lock.release()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;bark(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formated_frame_stack&nbsp;=&nbsp;self._get_formated_frame_stack()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.echo:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">print</span>(<span style="color: #800000; ">"</span><span style="color: #800000; ">!!!!!&nbsp;WATCH&nbsp;DOG&nbsp;FAILURE&nbsp;TRIGGERED&nbsp;!!!!!\n</span><span style="color: #800000; ">"</span>&nbsp;+&nbsp;formated_frame_stack)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;logger.fatal("!!!!!&nbsp;WATCH&nbsp;DOG&nbsp;FAILURE&nbsp;TRIGGERED&nbsp;!!!!!\n"&nbsp;+&nbsp;formated_frame_stack)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pid&nbsp;=&nbsp;os.getpid()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os.kill(pid,&nbsp;2)&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;通知进程退出</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(5)&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;等待5秒</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os.kill(pid,&nbsp;9)&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;发送强制退出</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;run(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;self.terminated:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;time.time()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is_timeout&nbsp;=&nbsp;ts&nbsp;-&nbsp;self.last_kicked_ts&nbsp;&gt;&nbsp;self.timeout<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.lock.release()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;is_timeout:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.bark()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;=&nbsp;int(max(self.timeout&nbsp;/&nbsp;3,&nbsp;1))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(n*10):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(0.1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.terminated:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;@staticmethod<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_get_thread(tid):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;t&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;threading.enumerate():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;t.ident&nbsp;==&nbsp;tid:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;t<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;None<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;@staticmethod<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_get_frame_stack(tid):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;thread_id,&nbsp;stack&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;sys._current_frames().items():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;thread_id&nbsp;==&nbsp;tid:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;stack<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;None<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_get_formated_frame_stack(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info&nbsp;=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;th&nbsp;=&nbsp;self._get_thread(self.thread_id)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack&nbsp;=&nbsp;self._get_frame_stack(self.thread_id)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info.append(<span style="color: #800000; ">'</span><span style="color: #800000; ">%s&nbsp;thead_id=%d</span><span style="color: #800000; ">'</span>&nbsp;%&nbsp;(th.name,&nbsp;self.thread_id))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;filename,&nbsp;lineno,&nbsp;_,&nbsp;line&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;traceback.extract_stack(stack):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info.append(<span style="color: #800000; ">'</span><span style="color: #800000; ">&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;%s(%s:%d)</span><span style="color: #800000; ">'</span>&nbsp;%&nbsp;(line,&nbsp;filename[filename.rfind(os.path.sep)&nbsp;+&nbsp;1:],&nbsp;lineno))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">\n</span><span style="color: #800000; ">'</span>.join(info)<br /><br /><br /><span style="color: #0000FF; ">def</span>&nbsp;watch_dog(timeout=10,&nbsp;echo=False):<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;inner(func):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;wrapper(*args,&nbsp;**kw):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dog&nbsp;=&nbsp;WatchDog(timeout=timeout,&nbsp;echo=echo)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;func(*args,&nbsp;**kw)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dog.terminate()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;ret<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;wrapper<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;inner</div><br />用法：<br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br />dog&nbsp;=&nbsp;WatchDog(echo=True)<br /><span style="color: #0000FF; ">while</span>&nbsp;True:<br />&nbsp;&nbsp;&nbsp;&nbsp;consumer.workex(timeout_ms=100)<br />&nbsp;&nbsp;&nbsp;&nbsp;dog.kick()</div><img src ="http://www.cnitblog.com/luckydmz/aggbug/92113.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2020-03-17 15:32 <a href="http://www.cnitblog.com/luckydmz/archive/2020/03/17/92113.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下监视进程 崩溃挂掉后自动重启的shell脚本</title><link>http://www.cnitblog.com/luckydmz/archive/2020/02/10/92044.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 10 Feb 2020 08:06:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2020/02/10/92044.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92044.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2020/02/10/92044.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92044.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92044.html</trackback:ping><description><![CDATA[<br />最后用了最简答的方法，分割线下方的代码会出现在没崩溃的时候莫名其妙重启。<br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#&nbsp;!&nbsp;/bin/sh<br />appcmdline="$@"<br /><br /><span style="color: #0000FF; ">while</span>&nbsp;<span style="color: #0000FF; ">true</span><br /><span style="color: #0000FF; ">do</span><br />&nbsp;&nbsp;&nbsp;&nbsp;$appcmdline<br />&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;`date&nbsp;+%Y-%m-%d`&nbsp;`date&nbsp;+%H:%M:%S`&nbsp;"Restart&nbsp;after&nbsp;1&nbsp;secound."<br />&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;1<br />done</div>------------------以下为原文----------------------------<br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#&nbsp;!&nbsp;/bin/sh<br />appcmdline="$@"<br /><br />procnum=`ps&nbsp;-ef|grep&nbsp;"$appcmdline"|grep&nbsp;-v&nbsp;grep|wc&nbsp;-l`<br /><span style="color: #0000FF; ">if</span>&nbsp;[&nbsp;$procnum&nbsp;-eq&nbsp;1&nbsp;]&nbsp;<br />then<br />&nbsp;&nbsp;&nbsp;&nbsp;pkill&nbsp;-2&nbsp;-f&nbsp;"$appcmdline"<br />fi<br /><span style="color: #0000FF; ">while</span>&nbsp;<span style="color: #0000FF; ">true</span><br /><span style="color: #0000FF; ">do</span><br />&nbsp;&nbsp;&nbsp;&nbsp;procnum=`ps&nbsp;-ef|grep&nbsp;"$appcmdline"|grep&nbsp;-v&nbsp;grep|wc&nbsp;-l`<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;[&nbsp;$procnum&nbsp;-eq&nbsp;0&nbsp;]<br />&nbsp;&nbsp;&nbsp;&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nohup&nbsp;$appcmdline&nbsp;1&gt;/dev/<span style="color: #0000FF; ">null</span>&nbsp;2&gt;&amp;1&nbsp;&amp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;`date&nbsp;+%Y-%m-%d`&nbsp;`date&nbsp;+%H:%M:%S`&nbsp;"restart"&nbsp;$appcmdline<br />&nbsp;&nbsp;&nbsp;&nbsp;fi<br />&nbsp;&nbsp;&nbsp;&nbsp;sleep&nbsp;1<br />done</div><br />可以存为 /usr/local/bin/supervised_run.sh<br />通过运行<br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->supervised_run.sh&nbsp;sleep&nbsp;5</div>可以看到每5-6秒钟会输出一次restart sleep 5，因为sleep每5秒自动退出，然后supervised_run.sh检测到sleep 5没在执行，于是重新执行sleep 5<img src ="http://www.cnitblog.com/luckydmz/aggbug/92044.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2020-02-10 16:06 <a href="http://www.cnitblog.com/luckydmz/archive/2020/02/10/92044.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python实现的一个消息总线+计划任务 Driver</title><link>http://www.cnitblog.com/luckydmz/archive/2020/01/21/92025.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 21 Jan 2020 06:28:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2020/01/21/92025.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92025.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2020/01/21/92025.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92025.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92025.html</trackback:ping><description><![CDATA[<div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br /><span style="color: #0000FF; ">import</span>&nbsp;threading<br /><span style="color: #0000FF; ">import</span>&nbsp;time<br /><span style="color: #0000FF; ">import</span>&nbsp;queue<br /><span style="color: #0000FF; ">from</span>&nbsp;dataclasses&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;dataclass,&nbsp;field<br /><span style="color: #0000FF; ">from</span>&nbsp;typing&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;Any<br /><br />@dataclass(order=True)<br /><span style="color: #0000FF; ">class</span>&nbsp;ScheduledItem:<br />&nbsp;&nbsp;&nbsp;&nbsp;time_sec:&nbsp;float<br />&nbsp;&nbsp;&nbsp;&nbsp;cb:&nbsp;Any&nbsp;=&nbsp;field(compare=False)<br /><br /><span style="color: #0000FF; ">class</span>&nbsp;Driver:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;<span style="color: #800080; ">__init__</span>(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled&nbsp;=&nbsp;queue.PriorityQueue()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every_lock&nbsp;=&nbsp;threading.Lock()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every&nbsp;=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock&nbsp;=&nbsp;threading.Lock()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks&nbsp;=&nbsp;{}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.async_queue&nbsp;=&nbsp;queue.Queue()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.epoch_sec&nbsp;=&nbsp;time.time()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.last_epoch&nbsp;=&nbsp;None<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;得到driver内的当前时间秒数</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;get_epoch(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;self.epoch_sec<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;执行一趟主逻辑，一般放在主循环中执行</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;run(self,&nbsp;wait_sync_interval=0):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.epoch_sec&nbsp;=&nbsp;time.time()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.last_epoch&nbsp;<span style="color: #0000FF; ">is</span>&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;None:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;self.epoch_sec&nbsp;-&nbsp;self.last_epoch&nbsp;&lt;&nbsp;wait_sync_interval:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;=&nbsp;wait_sync_interval&nbsp;-&nbsp;(self.epoch_sec&nbsp;-&nbsp;self.last_epoch)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(t)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.epoch_sec&nbsp;=&nbsp;time.time()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.last_epoch&nbsp;=&nbsp;self.epoch_sec<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._do_async()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._do_schedule()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._do_schedule_every()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;计划单次定时任务</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;schedule(self,&nbsp;cb,&nbsp;time_sec):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled.put_nowait(&nbsp;ScheduledItem(time_sec,&nbsp;cb)&nbsp;)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;计划重复任务</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;schedule_every(self,&nbsp;cb,&nbsp;interval_sec):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every_lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every.append(&nbsp;{&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">next_sec</span><span style="color: #800000; ">"</span>:self.epoch_sec+interval_sec,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">interval</span><span style="color: #800000; ">"</span>:interval_sec,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">cb</span><span style="color: #800000; ">"</span>:cb&nbsp;}&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every_lock.release()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;增加消息接收者</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;add_receiver(self,&nbsp;topic_or_type,&nbsp;cb):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;topic_or_type&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.callbacks:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks[topic_or_type]&nbsp;=&nbsp;set()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks[topic_or_type].add(cb)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.release()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;cb<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;删除消息接收者</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;remove_receiver(self,&nbsp;topic_or_type,&nbsp;cb):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;topic_or_type&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.callbacks:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;cb&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.callbacks[topic_or_type]:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks[topic_or_type].remove(cb)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.release()<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;同步发送消息</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;send(self,&nbsp;obj,&nbsp;topic=None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;topic&nbsp;==&nbsp;None:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;topic&nbsp;=&nbsp;type(obj)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cbs&nbsp;=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;topic&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.callbacks.keys():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cbs&nbsp;=&nbsp;list(self.callbacks[topic])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.callbacks_lock.release()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;cb&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;cbs:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cb(obj)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;异步发送消息</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;send_async(self,&nbsp;obj,&nbsp;topic=None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.async_queue.put_nowait(&nbsp;(obj,&nbsp;topic)&nbsp;)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_do_async(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;self.async_queue.empty():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.send(*self.async_queue.get_nowait())<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_do_schedule(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;<span style="color: #0000FF; ">not</span>&nbsp;self.scheduled.empty():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item&nbsp;=&nbsp;self.scheduled.get_nowait()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;item.time_sec&nbsp;&gt;&nbsp;self.epoch_sec:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled.put_nowait(item)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item.cb(self.epoch_sec)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_do_schedule_every(self):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cbs&nbsp;=&nbsp;[]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every_lock.acquire()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;o&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;self.scheduled_every:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;self.epoch_sec&nbsp;&gt;=&nbsp;o[<span style="color: #800000; ">"</span><span style="color: #800000; ">next_sec</span><span style="color: #800000; ">"</span>]:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cbs.append(o[<span style="color: #800000; ">"</span><span style="color: #800000; ">cb</span><span style="color: #800000; ">"</span>])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o[<span style="color: #800000; ">"</span><span style="color: #800000; ">next_sec</span><span style="color: #800000; ">"</span>]&nbsp;+=&nbsp;o[<span style="color: #800000; ">"</span><span style="color: #800000; ">interval</span><span style="color: #800000; ">"</span>]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.scheduled_every_lock.release()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;cb&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;cbs:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cb(self.epoch_sec)<br /><br /><br /><span style="color: #0000FF; ">def</span>&nbsp;bind(func,&nbsp;*args,&nbsp;**kw):<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">lambda</span>&nbsp;*_args,&nbsp;**_kw:&nbsp;func(*args,&nbsp;*_args,&nbsp;**kw,&nbsp;**_kw)<br /><br /><br />driver&nbsp;=&nbsp;Driver()</div><img src ="http://www.cnitblog.com/luckydmz/aggbug/92025.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2020-01-21 14:28 <a href="http://www.cnitblog.com/luckydmz/archive/2020/01/21/92025.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python SQLAlchemy的ORM模块用例，多数据库连接封装 </title><link>http://www.cnitblog.com/luckydmz/archive/2020/01/07/92009.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 07 Jan 2020 03:05:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2020/01/07/92009.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/92009.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2020/01/07/92009.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/92009.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/92009.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: db.pyCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#&nbsp;-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-from&nbsp;sqlalchemy&nbsp;import&nbsp;Table,&nbsp;Colu...&nbsp;&nbsp;<a href='http://www.cnitblog.com/luckydmz/archive/2020/01/07/92009.html'>阅读全文</a><img src ="http://www.cnitblog.com/luckydmz/aggbug/92009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2020-01-07 11:05 <a href="http://www.cnitblog.com/luckydmz/archive/2020/01/07/92009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过_CRTDBG_MAP_ALLOC宏在VC上启用内存泄漏检测</title><link>http://www.cnitblog.com/luckydmz/archive/2019/11/05/91938.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 04 Nov 2019 16:34:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2019/11/05/91938.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/91938.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2019/11/05/91938.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/91938.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/91938.html</trackback:ping><description><![CDATA[<div style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;"></div><div id="9230-1572884437045" data-theme="default" data-language="javascript" style="white-space: pre-wrap;"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">iostream</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">using</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">namespace</span><span style="color: #000000; ">&nbsp;std;<br /><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;_CRTDBG_MAP_ALLOC</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">crtdbg.h</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;按理说通过定义上面的宏再引入头文件，new就会被重新定义成记录文件和行号的<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;但是实际测试下来没有，不知道为什么，而手动定义是起作用的，Microsoft&nbsp;Visual&nbsp;C++&nbsp;2019&nbsp;16.3.2</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">#define</span><span style="color: #000000; ">&nbsp;new&nbsp;new(_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__)</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;还有其他选项，可以跳转到定义处查看<br />#define&nbsp;_CRTDBG_ALLOC_MEM_DF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x01&nbsp;&nbsp;//&nbsp;Turn&nbsp;on&nbsp;debug&nbsp;allocation<br />#define&nbsp;_CRTDBG_LEAK_CHECK_DF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x20&nbsp;&nbsp;//&nbsp;Leak&nbsp;check&nbsp;at&nbsp;program&nbsp;exit<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;当没有定义_DEBUG宏时，下面的调用会被替换成一个哑的宏，什么都不做</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF&nbsp;</span><span style="color: #000000; ">|</span><span style="color: #000000; ">&nbsp;_CRTDBG_LEAK_CHECK_DF);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">();<br />}</span></div>
</div><div style="white-space: pre-wrap; line-height: 1.75; font-size: 14px;"></div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">程序结束有会在输出栏输出如下信息，可以直接双击就会跳转到产生泄漏的文件和行号</div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">Detected memory leaks!</div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">Dumping objects -&gt;</div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">D:\development\cpp_test\Project1\main.cpp(21) : {82} normal block at 0x00000218B2905FC0, 4 bytes long.</div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">Data : &lt; &gt; 00 00 00 00</div><div style="white-space: pre-wrap; text-align: left; line-height: 1.75; font-size: 14px;">Object dump complete.</div><img src ="http://www.cnitblog.com/luckydmz/aggbug/91938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2019-11-05 00:34 <a href="http://www.cnitblog.com/luckydmz/archive/2019/11/05/91938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>给SELECT结果自动生成行号 (SQL Server)</title><link>http://www.cnitblog.com/luckydmz/archive/2019/06/04/91461.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 04 Jun 2019 03:32:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2019/06/04/91461.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/91461.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2019/06/04/91461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/91461.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/91461.html</trackback:ping><description><![CDATA[比如下面语句查询学生的 学号，姓名，年龄，按照年龄从小到大排序，年龄相同时按照学号从小到大排序
<div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">select</span>&nbsp;no,&nbsp;name,&nbsp;age&nbsp;<span style="color: #0000FF; ">from</span>&nbsp;Student<br />
<span style="color: #0000FF; ">order</span>&nbsp;<span style="color: #0000FF; ">by</span>&nbsp;age&nbsp;<span style="color: #0000FF; ">asc</span>,&nbsp;no&nbsp;<span style="color: #0000ff;">asc</span></div>
<br />
如果想给查询结果的每行前面加上一个从1开始的自然数编号，可以使用
<div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><span style="color: #0000ff;">select</span>&nbsp;ROW_NUMBER()&nbsp;<span style="color: #0000ff;">OVER</span>&nbsp;(<span style="color: #0000ff;">order</span>&nbsp;<span style="color: #0000ff;">by</span>&nbsp;age&nbsp;<span style="color: #0000ff;">asc</span>,&nbsp;no&nbsp;<span style="color: #0000ff;">asc</span>),&nbsp;no,&nbsp;name,&nbsp;age&nbsp;<span style="color: #0000ff;">from</span>&nbsp;Student<br />
<span style="color: #0000FF; ">order</span>&nbsp;<span style="color: #0000FF; ">by</span>&nbsp;age&nbsp;<span style="color: #0000FF; ">asc</span>,&nbsp;no&nbsp;<span style="color: #0000ff;">asc</span></div>
增加的部分<br /><div style="background-color: #eeeeee; font-size: 13px; border-color: #cccccc; border-image: initial; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->ROW_NUMBER()&nbsp;<span style="color: #0000FF; ">OVER</span>&nbsp;(<span style="color: #0000FF; ">order</span>&nbsp;<span style="color: #0000FF; ">by</span>&nbsp;age&nbsp;<span style="color: #0000FF; ">asc</span>,&nbsp;no&nbsp;<span style="color: #0000FF; ">asc</span>)</div>注意OVER后面的order by的内容和查询语句的order by是一致的，这样查询结果就是从1递增进行编号，事实上也可以不一致，这里的order by就是指定按照何种顺序生成这列值<br /><br />更详细的用法参考<br />https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql?view=sql-server-2017<img src ="http://www.cnitblog.com/luckydmz/aggbug/91461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2019-06-04 11:32 <a href="http://www.cnitblog.com/luckydmz/archive/2019/06/04/91461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mutex &amp; memory fence</title><link>http://www.cnitblog.com/luckydmz/archive/2014/12/01/89874.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 01 Dec 2014 05:53:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2014/12/01/89874.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/89874.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2014/12/01/89874.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/89874.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/89874.html</trackback:ping><description><![CDATA[<div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="background-color: inherit; line-height: 1.5;">mutex其实除了锁住数据只被一个线程同时访问，还隐含了</span><span style="background-color: inherit; line-height: 1.5;">__sync_synchronize() (大概意思是多核的时候保证每个核的cache都和mem同步了</span><span style="background-color: inherit; line-height: 1.5;">)</span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><p style="margin: 5px 0px; background-color: inherit;">一个例子：<br style="background-color: inherit;" />Processor #1:<br style="background-color: inherit;" /></p><p style="margin: 5px 0px; background-color: inherit;">while (f == 0); </p><p style="margin: 5px 0px; background-color: inherit;">// Memory fence required here </p><p style="margin: 5px 0px; background-color: inherit;">print x;</p><p style="margin: 5px 0px; background-color: inherit;"><br style="background-color: inherit;" /></p><p style="margin: 5px 0px; background-color: inherit;">Processor #2:<br style="background-color: inherit;" />x = 42; </p><p style="margin: 5px 0px; background-color: inherit;">// Memory fence required here </p><p style="margin: 5px 0px; background-color: inherit;">f = 1;</p></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">上面的例子中，变量 x f 初始化值都是0。我们期望输出&#8220;42&#8221;。但是结果并不总是这样。<br style="background-color: inherit;" />如果存储操作是乱序的，我觉得实际上并不是说上面的语句执行顺序颠倒，而可能是<span style="background-color: #ffffff; line-height: 1.5;">Processor #2上</span><span style="background-color: inherit; line-height: 1.5;">包含了f的那块cache比包含了x的那块cache先和mem进行了同步，这样的结果对于</span><span style="background-color: #ffffff; line-height: 1.5;">Processor #1来说</span><span style="background-color: inherit; line-height: 1.5;">，就相当于对f赋值的语句先于对x赋值的语句，那么就有会输出&#8220;0&#8221;</span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">在注释的地方加入<span style="background-color: #ffffff; line-height: 1.5;">__sync_synchronize()语句就可以解决这个问题，确保输出&#8220;42&#8221;。</span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">我们之所以从来没关心过这个问题，是因为对于类似上面的代码，我们一般会用mutex对f和x的访问进行加锁，而mutex隐含了<span style="background-color: #ffffff; line-height: 1.5;">__sync_synchronize()。</span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="background-color: inherit; line-height: 1.5;"><br style="background-color: inherit;" /></span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="background-color: inherit; line-height: 1.5;">参考</span></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="http://mortoray.com/2010/11/18/cpu-memory-why-do-i-need-a-mutex/" style="background-color: inherit; cursor: pointer;">http://mortoray.com/2010/11/18/cpu-memory-why-do-i-need-a-mutex/</a></div><div style="background-color: #ffffff; color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="http://en.wikipedia.org/wiki/Memory_barrier" style="background-color: inherit; cursor: pointer;">http://en.wikipedia.org/wiki/Memory_barrier</a></div></div><img src ="http://www.cnitblog.com/luckydmz/aggbug/89874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2014-12-01 13:53 <a href="http://www.cnitblog.com/luckydmz/archive/2014/12/01/89874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何成为一名优秀的程序员</title><link>http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Fri, 28 Mar 2014 03:51:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/89364.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/89364.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/89364.html</trackback:ping><description><![CDATA[<div>转载请保留原帖地址：<a id="Editor_Edit_hlEntryLink" title="view: 如何成为一名优秀的程序员" href="http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html" target="_blank">http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html</a><br /><br />我曾经是一名黑客，我购买黑客杂志期刊，关注最新的漏洞利用，那时候电脑安装的操作系统主要是WinXP和Win2000，很多人使用弱口令甚至空口令，随便选一个网段用扫描软件一扫就一堆肉鸡（黑客对可以被远程控制的机器的称呼），再加上各种服务的缓冲区溢出漏洞，SQL注入漏洞，网络环境安全当时可谓一塌糊涂，我入侵过很多个人电脑，也入侵过一些服务器，甚至通过键盘记录器得到过一些人的账户和密码甚至是ADSL密码，当时是可以通过ADSL进行某些购买的，不过我从未利用这些获取过任何利益，也没有进行过任何破坏行动，我只是觉得很有成就感，当时的我就沉浸在这所谓的黑客技术中。逐渐不再满足于使用别人提供的工具，我想搞清楚他们的原理以便可以利用最新的漏洞，我接触到一些漏洞的溢出源代码，它们一般是用C语言描述的，而我不知道如何使用它，还有一些论坛上会讨论如何使用反汇编对软件进行破解或者找到其中的漏洞，而我对这些一窍不通，我发现我根本不懂什么真正的技术，如果没有别人的工具我什么都不会，制作工具的那些人才是真正的黑客，他们掌握的才是真正的技术。从那时起我就认识到要学习编程，编程才是真正的技术，然后我便从书店买了一本《C++捷径教程》并开始了我的编程生涯，那一年我在读高二。<br /><br />&#8230;&#8230;<br /><br />之后我一直在学习编程，不过却再没踏上黑客之路，如今我已从计算机专业毕业，并在游戏开发行业从业近5年了，算起来我学习和使用C/C++已经10年有余了。<br /><br />好吧，这个引子有点可能长了，我只想说明相比刚刚学会写图形界面的妄自尊大的初学者就在论坛上侃侃而谈指点他人或许我的意见更具说服力。<br />现在我经常看到一些初学者在编程论坛和QQ群里询问该如何学习编程，有人问已经已经学了C还要不要学C++，已经学了C++还要不要学JAVA，要不要学C#，诸如此类要学习哪些语言的问题，有人会回答他们&#8220;是的，你需要学习Java，C语言已经过时了。&#8221;，&#8220;现在学习C语言已经找不到工作了，你还是学习C#吧&#8221;，可能还有更多人有类似疑问我根本没有遇到，这些初学者可能将花费大量时间在肤浅的层面徘徊，有时我会去指导他们，但是遇到得多了我也疲于指导了。<br />我并不是说多学习一些不同的语言不好，相反，学习不同的语言确实可以开拓思路，但我不提倡初学者接连甚至同时学习不同的语言，因为编程的精髓不在语言，语言只是对思想的一种描述形式，事实上除了上面提到的C++我也接触和使用过很多其他语言，C, VB, FORTRAN, JAVA, C#, PHP, Javascript, SQL, ASP.NET, LUA, RUBY, 而我学习这些语言的时间越晚我就学习得越快，只要花几天学习一下基础语法，然后写一些DEMO，一边写一边查文档学习使用标准库，用不了一个月就可以基本掌握这门语言。因为我已经掌握了一些编程本质的东西。<br /><br />如果说语言是肤浅的，那编程的内在究竟是什么呢？我们应该如何修炼编程&#8220;内功&#8221;呢？<br />我将这些知识划分为3个方面<br />1. 数学、算法和数据结构<br />2. 编码规范和设计模式<br />3. 开发实践和团队领导<br />其中2个方面有关个人能力的培养，1个方面有关团队建设和开发管理。<br /><br />接下来我将通过3篇BLOG将分别就这三方面的能力培养和相关书籍分别阐述 (超链接和BLOG以后将慢慢补全)<br /><br /><strong><a href="http://www.cnitblog.com/luckydmz/archive/2014/03/28/89365.html">如何成为一名优秀的程序员&#8212;&#8212;数学&amp;算法篇</a><br /><a href="http://www.cnitblog.com/luckydmz/archive/2014/07/09/89655.html">如何成为一名优秀的程序员&#8212;&#8212;编码&amp;设计篇</a> <br />如何成为一名优秀的程序员&#8212;&#8212;开发实践&amp;团队领导篇</strong></div><img src ="http://www.cnitblog.com/luckydmz/aggbug/89364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2014-03-28 11:51 <a href="http://www.cnitblog.com/luckydmz/archive/2014/03/28/89364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序异常控制</title><link>http://www.cnitblog.com/luckydmz/archive/2012/01/04/77011.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 03 Jan 2012 16:01:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2012/01/04/77011.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/77011.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2012/01/04/77011.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/77011.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/77011.html</trackback:ping><description><![CDATA[<p>有时我们希望在程序崩溃时保存一些信息来帮助调试，尤其是在Release版程序 </p><p>这时我们可以使用SetUnhandledExceptionFilter函数，MSDN对函数的描述是这样的</p> <table border="1" cellpadding="2" cellspacing="0" width="800"> <tbody> <tr> <td valign="top" width="798"> <h3><a name="base.setunhandledexceptionfilter"></a>SetUnhandledExceptionFilter</h3> <p>The <strong>SetUnhandledExceptionFilter</strong> function enables an application to supersede the top-level exception handler of each thread and process. </p><p>After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the unhandled exception filter, that filter will call the exception filter function specified by the <em>lpTopLevelExceptionFilter</em> parameter.</p><pre><strong>LPTOP_LEVEL_EXCEPTION_FILTER</strong> <strong>SetUnhandledExceptionFilter(</strong>
  <strong>LPTOP_LEVEL_EXCEPTION_FILTER</strong> <em>lpTopLevelExceptionFilter</em><strong></strong><strong>
</strong><strong>);</strong>
</pre>
<h6>Parameters</h6>
<dl>
<dt><em>lpTopLevelExceptionFilter</em>
</dt><dd>[in] Pointer to a top-level exception filter function that will be called whenever the <strong>UnhandledExceptionFilter</strong> function gets control, and the process is not being debugged. A value of NULL for this parameter specifies default handling within <strong>UnhandledExceptionFilter</strong>. 
<p>The filter function has syntax similar to that of <strong>UnhandledExceptionFilter</strong>: It takes a single parameter of type <strong>LPEXCEPTION_POINTERS</strong>, has a WINAPI calling convention, and returns a value of type <strong>LONG</strong>. The filter function should return one of the following values.
</p><p>Value<br />Meaning
</p><p><font color="#ff0000">EXCEPTION_EXECUTE_HANDLER<br /></font>0x1<br />Return from <strong>UnhandledExceptionFilter</strong> and execute the associated exception handler. This usually results in process termination.
</p><p><font color="#ff0000">EXCEPTION_CONTINUE_EXECUTION<br /></font>0xffffffff<br />Return from <strong>UnhandledExceptionFilter</strong> and continue execution from the point of the exception. Note that the filter function is free to modify the continuation state by modifying the exception information supplied through its <strong>LPEXCEPTION_POINTERS</strong> parameter.
</p><p><font color="#ff0000">EXCEPTION_CONTINUE_SEARCH<br /></font>0x0<br />Proceed with normal execution of <strong>UnhandledExceptionFilter</strong>. That means obeying the <strong>SetErrorMode</strong> flags, or <font color="#ff0000">invoking the Application Error pop-up message box</font>.</p></dd></dl>
<h6>Return Values</h6>
<p>The <a><strong>SetUnhandledExceptionFilter</strong></a> function <font color="#ff0000">returns the address of the previous exception filter</font> established with the function. A NULL return value means that there is no current top-level exception handler.
</p><h6>Remarks</h6>
<p>Issuing <a><strong>SetUnhandledExceptionFilter</strong></a> replaces the existing top-level exception filter for all existing and all future threads in the calling process.
</p><p>The exception handler specified by <em>lpTopLevelExceptionFilter</em> is executed in the context of the thread that caused the fault. This can affect the exception handler's ability to recover from certain exceptions, such as an invalid stack.</p></td></tr></tbody></table>
<p>上面的红字是我做的重点标注，通过注册的回调函数的返回值我们可以控制是否弹出程序崩溃的对话框。
</p><p>EXCEPTION_EXECUTE_HANDLER 表示结束程序但不弹出崩溃对话框。从宏的拼写上可以认为我处理了这个异常<br />EXCEPTION_CONTINUE_EXECUTION 表示错误已经被修复，继续执行，这是一个不应该被使用的返回值，因为一个设计良好的程序不会把错误处理放在这个步骤中。<br />EXCEPTION_CONTINUE_SEARCH 表示结束程序并弹出一个崩溃对话框。从宏的拼写上可以认为我没有处理这个异常，请继续搜索其他的handler</p>
<p>事实上只能有一个回调函数被同时注册，因此如果我们想让所有注册过的回调函数都能执行到的话需要接收<a><strong>SetUnhandledExceptionFilter</strong></a> 的返回值，即<font color="#ff0000">the address of the previous exception filter</font><font color="#000000">并在回调函数中调用，像这样</font></p><pre class="code"><span style="color: #020002">LPTOP_LEVEL_EXCEPTION_FILTER g_preFilter</span>;
<span style="color: #020002">LONG WINAPI func</span>( <span style="color: #020002">PEXCEPTION_POINTERS pExceptionInfo </span>)
{
    <span style="color: green">//...

    </span><span style="color: blue">if</span>(<span style="color: #020002">g_preFilter</span>)
        <span style="color: blue">return </span><span style="color: #020002">g_preFilter</span>(<span style="color: #020002">pExceptionInfo</span>);
    <span style="color: blue">else
        return </span><span style="color: #020002">EXCEPTION_CONTINUE_SEARCH</span>;
}

<span style="color: blue">int </span><span style="color: #020002">main </span>()
{
    <span style="color: #020002">g_preFilter </span>= <span style="color: #020002">SetUnhandledExceptionFilter</span>(<span style="color: #020002">func</span>);
    <span style="color: green">///...
    </span><span style="color: blue">return </span>0;
}
</pre><a href="http://11011.net/software/vspaste"></a>
<p>我们也可以做成，只在preFilter执行返回<font color="#ff0000">EXCEPTION_CONTINUE_SEARCH<font color="#000000">的时候才处理这个异常</font></font></p><pre class="code"><span style="color: #020002">LPTOP_LEVEL_EXCEPTION_FILTER g_preFilter</span>;
<span style="color: #020002">LONG WINAPI func</span>( <span style="color: #020002">PEXCEPTION_POINTERS pExceptionInfo </span>)
{
    <span style="color: #020002">LONG res</span>;
    <span style="color: blue">if</span>(<span style="color: #020002">g_preFilter</span>==<span style="color: #020002">NULL </span>|| (<span style="color: #020002">res </span>= <span style="color: #020002">g_preFilter</span>(<span style="color: #020002">pExceptionInfo</span>)) == <span style="color: #020002">EXCEPTION_CONTINUE_SEARCH</span>)
    {
        <span style="color: green">//...
        </span><span style="color: blue">return </span><span style="color: #020002">EXCEPTION_CONTINUE_SEARCH</span>;
    }
    <span style="color: blue">else
    </span>{
        <span style="color: blue">return </span><span style="color: #020002">res</span>;
    }
}

<span style="color: blue">int </span><span style="color: #020002">main </span>()
{
    <span style="color: #020002">g_preFilter </span>= <span style="color: #020002">SetUnhandledExceptionFilter</span>(<span style="color: #020002">func</span>);
    <span style="color: green">///...
    </span><span style="color: blue">return </span>0;
}</pre>
<p>这要根据实际的应用情况决定。</p>
<p>关于如何保留下当时的调用堆栈等信息是个复杂的主题，不过已经有前辈做过这件事了。</p>
<p>附件中包含一个异常处理机制，会在程序崩溃时生成一份报告文件和一份DUMP文件。</p><p><a href="http://www.cnitblog.com/Files/luckydmz/WheatyExceptionReport.rar">WheatyExceptionReport.rar</a><br /></p> <img src ="http://www.cnitblog.com/luckydmz/aggbug/77011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2012-01-04 00:01 <a href="http://www.cnitblog.com/luckydmz/archive/2012/01/04/77011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>平行分割阴影图(PSSMs)的研究</title><link>http://www.cnitblog.com/luckydmz/archive/2012/01/02/76993.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 02 Jan 2012 13:34:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2012/01/02/76993.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/76993.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2012/01/02/76993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/76993.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/76993.html</trackback:ping><description><![CDATA[<p>一．简介  <p>目前的阴影算法大致可以分为以下三类：基于ray tracing，基于shadow volume，基于shadow map。shadow map因其易于实现，算法复杂度与场景复杂度无关等优点被广泛应用，但是shadow map有alias（走样、锯齿）的问题。为解决这个问题，产生了诸多对标准shadow map的改进办法。  <p>Shadow map的alias问题可以分为两类：Perspective alias和Project alias。Project alias是因为当光照方向与物体表面夹角比较小时，使得多个pixel对应Shadow map中一个texel，产生alias问题，此类alias目前是个困难问题，针对这类alias的研究有Resolution-Matched SMs (Lefohn et al. 2007), Irregular Z-Buffer (Johnson et al.2005)，但都需要承受很大性能损失。Perspective alias产生的原因是透视投影会产生近大远小的效果，这使得近处物体的多个pixel可能对应着Shadow map中一个texel, 产生alias问题。相比其他流行的shadow map技术，如perspective shadow maps (PSMs) (Stamminger and Drettakis 2002), light-space perspective shadow maps (LiSPSMs) (Wimmer et al. 2004) and trapezoidal shadow maps (TSMs) (Martin and Tan 2004)，本文介绍的Parallel-Split Shadow Maps (PSSMs) (Zhang et al. 2007 and Zhang et al. 2006) 思想相对直观，实现也比较简单，并且不需要根据不同类型的关于和特殊的位置对映射进行任何特化处理，而且可以和其他的shadow map算法结合使用。  <p>PSSMs的基本思路就是把摄像机的视域体按照Z的范围平行分割成多个部份，每个部分称为一个子视域体，分别为对每个子视域体生成Shaodw Map，在渲染场景时根据Z值选择最适合的Shaodw Map进行采样。  <p>二．算法  <p><a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image002_2955D3CC.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image002_thumb_4904AD94.gif" width="553" height="340"></a>  <p>PSSMs算法的主要步骤如下：  <p>1) 将摄像机视域体按深度范围划分成多个子视域体{V1,V2,...,Vm}。  <p>2) 根据各相机子视域体分别计算各光源子视域体{W1,W2,...,Wm}。  <p>3) 生成阴影图，将Wi包含的阴影投射对象渲染到阴影图Ti中。  <p>4) 综合场景阴影效果，Vi中的像素采样Ti进行阴影判断。  <p>Step1. 分割摄像机视域体  <p><a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image004_4FB7B717.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image004_thumb_6F6690DF.gif" width="500" height="308"></a>  <p>如何分割视域体对PSSMs算法生成的阴影质量有着重要影响，若将视域体划分为m层，则摄像机空间下场景的划分平面深度值Ci可以通过  <p><i><a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image006_6AF01018.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image006_thumb_11BE2659.gif" width="313" height="133"></a></i><b></b>  <p>求得，其中f,n分别表示V的远近裁剪面，<a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image008_66798F51.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image008_thumb_13FAAF15.gif" width="36" height="27"></a>和<a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image010_417BCED8.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image010_thumb_1CEA4154.gif" width="36" height="25"></a>代表2种划分策略，参数<a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image012_1C7E0E5F.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image012_thumb_49FF2E22.gif" width="16" height="20"></a>用以调节他们的比例，分层策略的详细解释见参考文献[1]。  <p>Step2. 计算光源视域体及其变换矩阵  <p><a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image014_77804DE5.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image014_thumb_451C7A66.gif" width="400" height="324"></a>  <p>在计算子视域体Wi的view-projection矩阵之前，我们必须找到分割视域体Vi在光空间下的轴对齐包围盒。然后，我们引入cropMatrix的概念，cropMatrix是一个在投影空间内对规则观察体进行缩放和平移的矩阵，最终我们在以光源为视点进行阴影图Ti的渲染时使用的view-projection变换矩阵是  <p>lightViewMatrix * lightProjMatrix * cropMatrix  <p>当lightProjMatrix为正交投影时(对于平行光)，cropMatrix的作用相当于在世界空间内平移和缩放以光源为视点的视域体；  <p>当lightProjMatrix为透视投影时(对于点光源)，cropMatrix的作用相当于在世界空间内绕光源旋转和缩放以光源为视点的视域体。  <p>这正好符合平行光和点光源的特性，所以cropMatrix在平行光和点光源下都是正确的。  <p>我们使用如下函数来计算cropMatrix，  <p>Matrix4f CalcCropMatrix( Frustum splitFrustum, Matrix4f matViewProj);  <p>其中，  <p>参数 splitFrustum 是某个子视域体Vi。  <p>参数 matViewProj 是一个未经修剪的view-projection矩阵(即视矩阵和投影矩阵的复合)  <p>函数返回一个cropMatrix使得 matViewProj * cropMatrix所对应的规则观察体恰可以包住splitFrustum的轴对齐包围盒（AABB）。  <p>函数实现如下:  <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="568"><pre class="csharpcode">Matrix4f CalcCropMatrix( Frustum splitFrustum, Matrix4f matViewProj)
{
    <span class="rem">// 计算视域体splitFrustum在matViewProj空间下的轴对齐包围盒</span>
    BoundingBox cropBB = CalcAABB(splitFrustum, matViewProj); 

    <span class="rem">// 使用默认的近裁剪面</span>
    cropBB.min.z = 0.0f; 

    <span class="rem">// 计算缩放和偏移值</span>
    <span class="kwrd">float</span> scaleX, scaleY, scaleZ;
    <span class="kwrd">float</span> offsetX, offsetY, offsetZ;
    scaleX = 2.0f / (cropBB.max.x - cropBB.min.x);
    scaleY = 2.0f / (cropBB.max.y - cropBB.min.y);
    offsetX = -0.5f * (cropBB.max.x + cropBB.min.x) * scaleX;
    offsetY = -0.5f * (cropBB.max.y + cropBB.min.y) * scaleY;
    scaleZ = 1.0f / (cropBB.max.z - cropBB.min.z);
    offsetZ = -cropBB.min.z * scaleZ; 

    <span class="kwrd">return</span> Matrix4f(scaleX,  0.0f,     0.0f,  0.0f,
        0.0f,   scaleY,     0.0f,  0.0f,
        0.0f,     0.0f,   scaleZ,  0.0f,
        offsetX,  offsetY,  offsetZ,  1.0f);
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</td></tr></tbody></table>
<p>这里有几点需要说明的，cropBB.min.z = 0.0f表示使用默认的近裁剪面，即生成的cropMatrix不对参数matViewProj所定义的近裁剪面进行调整，如果使用由包围盒计算出的近裁剪面会导致从由matViewProj所定义的视点到包围盒之间的阴影投射体不会被渲染到阴影图上，那么其所产生的阴影就不会出现在包围盒内的物体上，如图2-3所示，Caster的阴影应该出现在Vi内的物体上，但Caster不在Vi所对应的AABB内。 
<p>还有一点需要注意的是应该保证splitFrustum 不会出现在matViewProj所对应的投影空间的Z轴的副半轴，否则生成cropMatrix将不正确。 
<p>Step3. 生成分段阴影图 
<p>在阴影图生成方面，在DX10上是可以优化到渲染一次的。而在DX9上如果将视域体分成N段的话需要渲染N次来生成N张不同子视域体的阴影图。如下图2-4： 
<p><a href="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image016_12B8A6E7.gif"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://www.cnitblog.com/images/cnitblog_com/luckydmz/clip_image016_thumb_0722E9A8.gif" width="553" height="552"></a> 
<p>在DX9上使用GPU加速的渲染流程大致如下： 
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568"><pre class="csharpcode">Matrix4f lightViewProjMatrix[numSplits];
<span class="rem">//生成光源深度图</span>
<span class="kwrd">for</span>(<span class="kwrd">int</span> i=0;i&lt;numSplits;i++)
{ 
    <span class="rem">//设置阴影图为RenderTarget</span>
    GetRenderDevice()-&gt;BeginRenderToTargets(m_pTexShadowMap[i]));
    GetRenderDevice()-&gt;Clear(); 

    <span class="rem">//计算子视域体</span>
    splitFrustum = camera-&gt;CalculateFrustum(splitPos[i], splitPos[i+1]);
    <span class="rem">//计算cropMatrix</span>
    cropMatrix = CalcCropMatrix(splitFrustum, lightViewMatrix * lightProjMatrix); 

    lightViewProjMatrix[i] = lightViewMatrix * lightProjMatrix * cropMatrix;
    <span class="rem">//以lightViewMatrix * lightProjMatrix * cropMatrix为ViewProj变换渲染阴影投射体</span>
    RenderCasters(casters, lightViewProjMatrix[i]); 

    GetRenderDevice()-&gt;EndRenderToTargets();
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</td></tr></tbody></table>
<p>Step4. 合成场景阴影效果 
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568"><pre class="csharpcode"><span class="kwrd">for</span>(<span class="kwrd">int</span> i=0;i&lt;numSplits;i++)
{
    <span class="rem">//设置各个子视域体的光源ViewProj矩阵</span>
    GetRenderDevice()-&gt;ShaderSetConstant(ShaderStage::VERTEX_SHADER_STAGE, <br>        LIGHT_VPMATRIX_REGISTER+i*4, &amp;lightViewProjMatrix[i]);<br>
    <span class="rem">//设置各个子视域体生成的阴影图</span>
    GetRenderDevice()-&gt;ShaderSetConstant(ShaderStage::PIXEL_SHADER_STAGE, <br>        SHADOWMAP_REGISTER+i, m_pTexShadowMap[i]);
}
<span class="rem">//以摄像机的ViewProj变换渲染阴影接收体</span>
RenderReivers(receivers, camera-&gt;viewMatrix * camera-&gt;projMatrix); 
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</td></tr></tbody></table>
<p>Vertex and Pixel Shaders for Synthesizing Shadows in DirectX 9 
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568"><pre class="csharpcode"><span class="kwrd">struct</span> VS_IN
{
    float3 ObjPos    : POSITION;
    float2 ObjUV     : TEXCOORD2;
}; 

<span class="kwrd">struct</span> VS_OUT
{
    float4 ProjPos   : POSITION;
    float2 ObjUV     : TEXCOORD2;
    <span class="kwrd">float</span>  viewZ     : TEXCOORD3;
    float4 texCoordProj[3] : TEXCOORD4;
}; 

float4x4 matWorld : register(c0);
float4x4 matView : register(c4);
float4x4 matProj : register(c8);
float4x4 matLightVP[3] : register(c12); 

VS_OUT main( VS_IN In )
{
    float4 wPosition = mul(float4(In.ObjPos.xyz, 1.0f), matWorld);
    float4 vPosition = mul(wPosition, matView);
    VS_OUT Out;
    Out.ProjPos = mul( vPosition, matProj );
    Out.ObjUV = In.ObjUV; 

    Out.viewZ = vPosition.z;
    float4x4 matLightViewport = float4x4(
        0.5f,  0.0f,  0.0f,  0.0f,
        0.0f, -0.5f,  0.0f,  0.0f,
        0.0f,  0.0f,  1.0f,  0.0f,
        0.5f + 0.5f / 512.0f,  0.5f + 0.5f / 512.0f,  0,  1.0f
        );
    <span class="kwrd">for</span>(<span class="kwrd">int</span> i=0;i&lt;3;i++)
    {
        Out.texCoordProj[i] = mul( wPosition, matLightVP[i] );
        Out.texCoordProj[i] = mul( Out.texCoordProj[i], matLightViewport);
    } 

    <span class="kwrd">return</span> Out;
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</td></tr></tbody></table>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568"><pre class="csharpcode"><span class="kwrd">struct</span> PS_IN
{
    float2 ObjUV     : TEXCOORD2;
    <span class="kwrd">float</span>  viewZ     : TEXCOORD3;
    float4 texCoordProj[3] : TEXCOORD4;
}; 

sampler2D g_Tex : register(s0);
sampler2D g_tShadowMap[3] : register(s1); 

float4 main( PS_IN In ) : COLOR
{
    <span class="kwrd">float</span> lightIntensity = 1.0; 

    <span class="kwrd">for</span>(<span class="kwrd">int</span> i=0;i&lt;3;i++)
    {
        <span class="kwrd">if</span>(In.viewZ &lt; splitPlane[i])
        {
            lightIntensity = tex2Dproj(g_tShadowMap[i], In.texCoordProj[i]).x;
        }
    } 

    float4 COLOR_IN_SHADOW, COLOR_IN_LIGHT;
    COLOR_IN_SHADOW.rgba = float4(0.2,0.2,0.2,1.0);
    COLOR_IN_LIGHT.rgba = float4(1.0,1.0,1.0,1.0); 

    float4 tex = tex2D(g_Tex, In.ObjUV);
    tex *= lerp(COLOR_IN_SHADOW, COLOR_IN_LIGHT, lightIntensity);
    <span class="kwrd">return</span> tex;
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</td></tr></tbody></table>
<p>&nbsp; <p>三．可能的优化 
<p>·结合使用Variance Shadow Maps和Gaussian Blur可进一步软化阴影边缘 
<p>·正反Culling渲染2次取平均深度可以帮助解决Shadow Acne &amp; Peter Panning 
<p>·将阴影图纹理打包，使用TextureArray或者拼到一张2D Texture上，可以减少PS的分支<br>参考文献： 
<p>[1] Zhang F, Sun H Q, Xu L L, et al. Hardware-accelerated parallel-split shadow maps[J]. International Journal of Image and Graphics, 2008.8(2): 223-241 
<p>[2] Zhang F, Sun H Q, Nyman O. Parallel-Split Shadow Maps on Programmable GPUs. GPU Gems 3 - Chapter 10, 2007: 203-238 
<img src ="http://www.cnitblog.com/luckydmz/aggbug/76993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2012-01-02 21:34 <a href="http://www.cnitblog.com/luckydmz/archive/2012/01/02/76993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于C++泛型函数指针</title><link>http://www.cnitblog.com/luckydmz/archive/2009/11/23/62785.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 23 Nov 2009 15:59:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2009/11/23/62785.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/62785.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2009/11/23/62785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/62785.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/62785.html</trackback:ping><description><![CDATA[如何实现Qt中signal/slot的绑定？<br>如何实现C#中的委托？<br><br>其核心在于定义一种泛型成员函数指针，但按照C++标准这似乎是不可能的，<br>C++的成员函数指针一直是一个比较难用的东西，可以说压根就没什么用。<br>关于上面两个问题我自己曾尝试了许多方法，未果，后，得知目前至少有两种东西可以帮助我实现<br>1. boost::function<br>2. FastDelegate&nbsp;&nbsp;&nbsp;&nbsp; (<a href="http://www.codeproject.com/KB/cpp/FastDelegate.aspx">http://www.codeproject.com/KB/cpp/FastDelegate.aspx</a>)<br><br>这两个东西都使用了非标准化的东西，不过FastDelegate的作者已经完成了所有主流C++编译器的测试，并且FastDelegate的调用只会生成2行汇编代码，可以和普通的函数指针调用一样迅速。<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">FastDelegate.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">using</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">namespace</span><span style="color: #000000;">&nbsp;fastdelegate;<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;add(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;a</span><span style="color: #000000;">+</span><span style="color: #000000;">b;<br>}<br><br></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Add<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">&nbsp;()(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;a</span><span style="color: #000000;">+</span><span style="color: #000000;">b;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;add(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;a</span><span style="color: #000000;">+</span><span style="color: #000000;">b;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;FastDelegate</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;theDelegate1,&nbsp;theDelegate2,&nbsp;theDelegate3;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;Add&nbsp;tempAddObj;<br>&nbsp;&nbsp;&nbsp;&nbsp;theDelegate1.bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">tempAddObj,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Add::</span><span style="color: #0000ff;">operator</span><span style="color: #000000;">()&nbsp;);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">绑定一个对象的成员函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;theDelegate1(</span><span style="color: #000000;">1</span><span style="color: #000000;">,</span><span style="color: #000000;">1</span><span style="color: #000000;">));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;theDelegate2.bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">add);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">绑定一个普通函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;theDelegate2(</span><span style="color: #000000;">1</span><span style="color: #000000;">,</span><span style="color: #000000;">2</span><span style="color: #000000;">));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;theDelegate3.bind(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">Add::add);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">绑定一个类的静态函数</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;theDelegate3(</span><span style="color: #000000;">1</span><span style="color: #000000;">,</span><span style="color: #000000;">3</span><span style="color: #000000;">));<br>}<br><br></span></div>
<br style="color: red;"><span style="color: red;">一年后，我发觉是可以用标准C++实现类似东西的</span><br style="color: red;"><span style="color: red;">http://www.cnitblog.com/luckydmz/archive/2010/11/15/71336.html</span><br>  <img src ="http://www.cnitblog.com/luckydmz/aggbug/62785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2009-11-23 23:59 <a href="http://www.cnitblog.com/luckydmz/archive/2009/11/23/62785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用c++的traits技术实现的任意类型元素的表达式求值</title><link>http://www.cnitblog.com/luckydmz/archive/2008/09/20/49295.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Fri, 19 Sep 2008 17:51:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2008/09/20/49295.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/49295.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2008/09/20/49295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/49295.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/49295.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这里以整形和浮点型表达式为例。Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#include&nbsp;&lt;iostream&gt;#include&nbsp;&lt;string&gt;#include&nbsp;&lt;cmath&gt;...&nbsp;&nbsp;<a href='http://www.cnitblog.com/luckydmz/archive/2008/09/20/49295.html'>阅读全文</a><img src ="http://www.cnitblog.com/luckydmz/aggbug/49295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2008-09-20 01:51 <a href="http://www.cnitblog.com/luckydmz/archive/2008/09/20/49295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>巧妙使用宏定义调试查看变量值</title><link>http://www.cnitblog.com/luckydmz/archive/2007/12/05/37372.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Wed, 05 Dec 2007 11:37:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2007/12/05/37372.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/37372.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2007/12/05/37372.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/37372.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/37372.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;Watch(X)&nbsp;&nbsp;printf(&nbsp;#X&nbsp;"=%d\n",(X))</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;b</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;Watch(a);<br>&nbsp;&nbsp;&nbsp;&nbsp;Watch(a</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b);<br>}<br></span></div>
对于我们这些不喜欢用调试工具的人，往往在程序中使用printf帮助调试，提交代码前再将调试用的printf全部注释掉。<br>最近发现一个更便捷的方法，如上。提交时只需<span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;Watch(X)&nbsp;&nbsp;//printf(&nbsp;#X&nbsp;"=%d\n",(X)) <span style="COLOR: red">更好的写法见一楼</span><br></span><span style="COLOR: #000000"><br>在宏定义中运用了两个不常用的语法，一个是#X,一个是字符串拼接<br>#X表示提取参数的名字，把它变成字符串。<br>而当两个字符串之间除空白符以外没有任何东西，编译器会自动认为这两个字符串是连在一起的字符串。<br>即"he" "llo" 相当于"hello"</span> 
<img src ="http://www.cnitblog.com/luckydmz/aggbug/37372.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2007-12-05 19:37 <a href="http://www.cnitblog.com/luckydmz/archive/2007/12/05/37372.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于数论中的同余</title><link>http://www.cnitblog.com/luckydmz/archive/2007/02/06/22722.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 05 Feb 2007 17:43:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2007/02/06/22722.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/22722.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2007/02/06/22722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/22722.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/22722.html</trackback:ping><description><![CDATA[<p>题目的大概意思是<br />
给出一个整数N ，0&lt;=N&lt;=10000,N既不是2的倍数又不是5的倍数，求一整数S，S既是N的倍数，且S的每一位都是1(在十进制的意义下)。输出S的数位。<br />
题目很简单，按照题目意思写出来如下代码：</p>
<p>int main()<br />
{<br />
&nbsp;int n;<br />
&nbsp;while(scanf("%d",&amp;n)!=EOF){<br />
&nbsp;&nbsp;int x=1;<br />
&nbsp;&nbsp;int i=1;<br />
&nbsp;&nbsp;while(x%n){<br />
&nbsp;&nbsp;&nbsp;x=(x*10+1);<br />
&nbsp;&nbsp;&nbsp;i++;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;printf("%d\n",i);<br />
&nbsp;}<br />
}<br />
但是sample都过不了，因为sample中就有一个输出是12，显然int不够长，然后我问了金XX，金告诉我不要大整数，大概10分钟后我又问了一次&#8230;&#8230;，然后他告诉我用到了&#8220;同余&#8221;，其实我本来也不是不知道，但是没想到可以这样用，也许第一次碰到这样的题目，看了数论的书，<br />
&#8220;a,b关于模m同余&#8221;是等价关系，记作a=b(mod m)<br />
若a1=a2(mod m),且b1=b2(mod m)，则a1+b1=a2+b2(mod m)<br />
若a1=a2(mod m),且b1=b2(mod m)，则a1*b1=a2*b2(mod m)<br />
<br />
回到题目x%n==0就是x=0(mod n)<br />
若x'=x(mod n),且10=10(mod n)，且1=1(mod n)，则x'*10+1=x*10+1(mod n)<br />
因此，不妨将x(mod n)记做x，这样就可以避免超过int的范围了</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;">
<span style="color: #008000;">//</span>
<span style="color: #008000;">2007-02-06&nbsp;00:48:10&nbsp;&nbsp;&nbsp;&nbsp;Accepted&nbsp;&nbsp;&nbsp;&nbsp;1889&nbsp;&nbsp;&nbsp;&nbsp;C++&nbsp;&nbsp;&nbsp;&nbsp;00:00.00&nbsp;&nbsp;&nbsp;&nbsp;832K<br />
</span>
<span style="color: #008000;">//</span>
<span style="color: #008000;">数论的同余<br />
</span>
<span style="color: #008000;">//</span>
<span style="color: #008000;">以后看到整除要想到同余，太有用了，见数论笔记</span>
<span style="color: #008000;">
<br />
</span>
<span style="color: #000000;">#include&nbsp;</span>
<span style="color: #000000;">&lt;</span>
<span style="color: #000000;">iostream</span>
<span style="color: #000000;">&gt;</span>
<span style="color: #000000;">
<br />
<br />
</span>
<span style="color: #0000ff;">using</span>
<span style="color: #000000;">&nbsp;</span>
<span style="color: #0000ff;">namespace</span>
<span style="color: #000000;">&nbsp;std;<br />
<br />
</span>
<span style="color: #0000ff;">int</span>
<span style="color: #000000;">&nbsp;main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color: #0000ff;">int</span>
<span style="color: #000000;">&nbsp;n;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color: #0000ff;">while</span>
<span style="color: #000000;">(scanf(</span>
<span style="color: #000000;">"</span>
<span style="color: #000000;">%d</span>
<span style="color: #000000;">"</span>
<span style="color: #000000;">,</span>
<span style="color: #000000;">&amp;</span>
<span style="color: #000000;">n)</span>
<span style="color: #000000;">!=</span>
<span style="color: #000000;">EOF){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color: #0000ff;">int</span>
<span style="color: #000000;">&nbsp;x</span>
<span style="color: #000000;">=</span>
<span style="color: #000000;">1</span>
<span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color: #0000ff;">int</span>
<span style="color: #000000;">&nbsp;i</span>
<span style="color: #000000;">=</span>
<span style="color: #000000;">1</span>
<span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color: #0000ff;">while</span>
<span style="color: #000000;">(x</span>
<span style="color: #000000;">%</span>
<span style="color: #000000;">n){//这里将%n去掉也可以，但是为了和上面的code对比，我还是保留着<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x</span>
<span style="color: #000000;">=</span>
<span style="color: #000000;">(x</span>
<span style="color: #000000;">*</span>
<span style="color: #000000;">10</span>
<span style="color: #000000;">+</span>
<span style="color: #000000;">1</span>
<span style="color: #000000;">)</span>
<span style="color: #000000;">%</span>
<span style="color: #000000;">n;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span>
<span style="color: #000000;">++</span>
<span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span>
<span style="color: #000000;">"</span>
<span style="color: #000000;">%d\n</span>
<span style="color: #000000;">"</span>
<span style="color: #000000;">,i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span>
</div>
<br />
再总结一下，若x'=x(mod n),则f(x')=f(x)(mod n),其中f表示<s>整数域上的多项式</s><span style="color: red;">整系数多项式(编辑:2011-06-24)</span><img src ="http://www.cnitblog.com/luckydmz/aggbug/22722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2007-02-06 01:43 <a href="http://www.cnitblog.com/luckydmz/archive/2007/02/06/22722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pskill</title><link>http://www.cnitblog.com/luckydmz/archive/2006/10/27/18525.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Fri, 27 Oct 2006 15:29:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/10/27/18525.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/18525.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/10/27/18525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/18525.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/18525.html</trackback:ping><description><![CDATA[
		<p>// (c) Anatoliy &amp; Taras Slobodskyy 2004<br />// Shecks if process is running and kills it if necessary [windows application]<br />// Compile with lcc-win32<br />// version 1.1</p>
		<p>#include &lt;windows.h&gt;<br />#include &lt;tlhelp32.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;string.h&gt;</p>
		<p>//  Forward declarations:</p>
		<p>int main( int argc, char *argv[] )<br />{<br />  HANDLE hProcessSnap;<br />  HANDLE hProcess;<br />  PROCESSENTRY32 pe32;<br />//  BOOL itruns;</p>
		<p>  if (argc&gt;1) {<br />   //initialize runing flag<br />//   itruns=0;</p>
		<p>   // Take a snapshot of all processes in the system.<br />   hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );</p>
		<p>   // Set the size of the structure before using it.<br />   pe32.dwSize = sizeof( PROCESSENTRY32 );</p>
		<p>   // Retrieve information about the first process,<br />   // and exit if unsuccessful<br />   Process32First( hProcessSnap, &amp;pe32 );<br />   // Now walk the snapshot of processes<br />   do<br />   {<br /> if (!strcmp(argv[1], pe32.szExeFile)) {<br />//  itruns=1;<br />  if (argc&gt;2) {<br />   hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );<br />   TerminateProcess( hProcess, (DWORD) -1 );<br />  } else {<br />   printf( "runs" );<br />   return 0;<br />  }<br /> }<br />   } while( Process32Next( hProcessSnap, &amp;pe32 ) );<br />//   if (!itruns) printf( "no" );<br />  } else {<br />   printf ("Use: pskill processname [c]\nc says to kill the process. It returns 'runs' if the process exists.");<br />  }<br />  return 1;<br />}<br /></p>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/18525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-10-27 23:29 <a href="http://www.cnitblog.com/luckydmz/archive/2006/10/27/18525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于\n变\r\n问题</title><link>http://www.cnitblog.com/luckydmz/archive/2006/10/25/18402.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Wed, 25 Oct 2006 13:31:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/10/25/18402.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/18402.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/10/25/18402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/18402.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/18402.html</trackback:ping><description><![CDATA[0A('\n')在ASCII中为换行符，而windows下的换行符用0D0A('\r''\n')表示<br />因此以文本方式处理文件时，C++会将一个换行符'\n'用一个回车符和一个换行符替代'\r''\n'<br />所以对于非文本文件，应该使用二进制模式打开<img src ="http://www.cnitblog.com/luckydmz/aggbug/18402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-10-25 21:31 <a href="http://www.cnitblog.com/luckydmz/archive/2006/10/25/18402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>KMP算法</title><link>http://www.cnitblog.com/luckydmz/archive/2006/10/21/18236.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Sat, 21 Oct 2006 12:27:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/10/21/18236.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/18236.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/10/21/18236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/18236.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/18236.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #0000ff">#define</span>
				<span style="COLOR: #000000"> B_MAX_LEN 2000</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> next[B_MAX_LEN];<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> Compute_Next(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> B[]){<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i;<br />    next[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">next[</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    </span>
				<span style="COLOR: #0000ff">for</span>
				<span style="COLOR: #000000">(i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">;B[i];i</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">){<br />        </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">next[i</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">];<br />        </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(B[i</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">]</span>
				<span style="COLOR: #000000">!=</span>
				<span style="COLOR: #000000">B[j] </span>
				<span style="COLOR: #000000">&amp;&amp;</span>
				<span style="COLOR: #000000"> j</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">)<br />            j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">next[j];<br />        </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(B[i</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">]</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">B[j])<br />            next[i]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">j</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000">
						<br />            next[i]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    }<br />}<br /><br /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">串匹配的KMP算法<br /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">返回A中第一个与B匹配的子串的指针，若找不到则返回NULL<br /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">需要已经对串B计算好next[]</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> String_Match(</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> A[],</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> B [])<br />{<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">,j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(A[i] </span>
				<span style="COLOR: #000000">&amp;&amp;</span>
				<span style="COLOR: #000000"> B[j]){<br />        </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(A[i]</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">B[j]){<br />            </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">i;<br />            </span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">j;<br />        }<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> {<br />            </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(j</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">)</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">i;<br />            </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #000000">!</span>
				<span style="COLOR: #000000">B[j])</span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br />            </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> j</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">next[j];<br />        }<br />    }<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #000000">!</span>
				<span style="COLOR: #000000">B[j])</span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">A[i</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">j];<br />    </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> NULL;<br />}<br /></span>
		</div>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/18236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-10-21 20:27 <a href="http://www.cnitblog.com/luckydmz/archive/2006/10/21/18236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZJU1104</title><link>http://www.cnitblog.com/luckydmz/archive/2006/09/10/16607.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Sat, 09 Sep 2006 17:38:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/09/10/16607.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/16607.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/09/10/16607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/16607.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/16607.html</trackback:ping><description><![CDATA[
		<p>//这题我试sample output的时候精度不够，差了0.01，修改了好多细节还是差0.01，试着提交居然一下就过了<br />//算法还有一些不足，paowuxian workout(point a,point b)中没有判断是否和(0,0)三点共线的问题<br />//但是if(Vec[i]&gt;pwx)可以避免掉a是x轴上的点(注释1处)</p>
		<p>#include &lt;iostream&gt;<br />#include &lt;vector&gt;<br />#include &lt;cmath&gt;<br />#include &lt;stdlib.h&gt;</p>
		<p>#define PI 3.141592653589793238<br />using namespace std;</p>
		<p>//过原点的抛物线y=ax^2+bx <br />class paowuxian{<br />public:<br />    double a;<br />    double b;<br />};    </p>
		<p>class point{<br />public:<br />    double x;<br />    double y;<br />};</p>
		<p>//返回过原点，点a,点b，的抛物线<br />//前提条件：三点不共线<br />paowuxian workout(point a,point b)<br />{<br />    paowuxian res;<br />    double a11,a12,a21,a22,b1,b2;<br />    a11=a.x*a.x;<br />    a12=a.x;<br />    a21=b.x*b.x;<br />    a22=b.x;<br />    b1=a.y;<br />    b2=b.y;<br />    res.a=(b1*a22-b2*a12)/(a11*a22-a21*a12);<br />    res.b=(a11*b2-a21*b1)/(a11*a22-a21*a12);<br />    return res;<br />}    </p>
		<p>//点p_a在抛物线pwx上方时返回真   <br />bool operator &gt; (point p_a,paowuxian pwx)<br />{<br />    return (p_a.y &gt; (pwx.a*p_a.x+pwx.b)*p_a.x);<br />}    </p>
		<p>int main()<br />{<br />    int n;<br />   vector&lt;point&gt; Vec;<br />   while(scanf("%d",&amp;n)!=EOF){<br />       point point_tmp;<br />       point_tmp.x=point_tmp.y=0.0;<br />       paowuxian pwx;<br />       Vec.clear();</p>
		<p>       //把点压入动态数组<br />       for(int i=0;i&lt;n;++i){<br />           double y,dx;<br />           scanf("%lf %lf",&amp;y,&amp;dx);<br />           point_tmp.y=y;<br />           Vec.push_back(point_tmp);//这里会取到一些显然不必要的点，有待改进<br />           point_tmp.x+=dx;<br />           Vec.push_back(point_tmp);<br />       }<br />       <br />       //为抛物线赋初值<br />       //pwx=workout(Vec.front(),Vec.back());<br />       pwx=workout(Vec[1],Vec.back());//目前Vec[0]是x轴上的点不能取，改进后需修改<br />       <br />       //如果有点在当前抛物线上方，则重新计算抛物线，最终包含所有点在下方<br />       for(int i=1;i&lt;Vec.size()-1;i++){<br />           if(Vec[i]&gt;pwx){//注释1<br />               pwx=workout(Vec[i],Vec.back());<br />           }    <br />       }<br />       //printf("%lf,%lf\n",pwx.a,pwx.b);<br />       point highest;//抛物线顶点<br />       highest.x=Vec.back().x/2;<br />       highest.y=highest.x*(highest.x*pwx.a+pwx.b);<br />       double angle_r,angle_d;//仰角的弧度表示和角度表示<br />       angle_r=atan(highest.y*2/highest.x);<br />       angle_d=angle_r*180/PI;<br />       //printf("%.2lf\n",angle);<br />       double vx,vy,velocity;<br />       vy=sqrt(2.0*9.8*highest.y);<br />       velocity=vy/sin(angle_r);<br />       printf("%.2lf %.2lf\n",angle_d,velocity);<br />   } <br />  return 0;<br />}</p>
		<p> </p>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/16607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-09-10 01:38 <a href="http://www.cnitblog.com/luckydmz/archive/2006/09/10/16607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用assert</title><link>http://www.cnitblog.com/luckydmz/archive/2006/07/04/13201.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Mon, 03 Jul 2006 16:27:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/07/04/13201.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/13201.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/07/04/13201.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/13201.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/13201.html</trackback:ping><description><![CDATA[如果函数或者语句有前置条件，至少要使用入口断言assert( )保证其运行的合法性//需要包含assert.h<br /><br />assert(条件) <br />如果条件不满足则会弹出对话框 <br /><br />技巧1 <br />assert(条件&amp;&amp;"说明信息") <br />由于对话框中会显示条件，因此可以利用这个特点显示说明信息，帮助定位错误 <br /><br />技巧2 <br />assert(!"说明信息") <br />因为assert(0)肯定会显示对话框，可以帮助提示程序运行到哪里了 <br /><br />技巧3 <br />#define Assert(a,b) assert(a&amp;&amp;b) <br />定义一个Assert宏，可以更好的使用技巧1 <br /><br />技巧4 <br />#define Assert(条件，"说明信息") <br />   if(条件){_asm{int 3}}    //满足条件中断 <img src ="http://www.cnitblog.com/luckydmz/aggbug/13201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-07-04 00:27 <a href="http://www.cnitblog.com/luckydmz/archive/2006/07/04/13201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++变量的内存使用，将变量按位输出</title><link>http://www.cnitblog.com/luckydmz/archive/2006/06/17/12401.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Fri, 16 Jun 2006 17:11:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/06/17/12401.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/12401.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/06/17/12401.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/12401.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/12401.html</trackback:ping><description><![CDATA[貌似C++/C中内存都是一个字节一个字节“倒着”用的<br />如，整数1，应该为00000000 00000000 00000000 00000001<br />而在内存中会被这样放 00000001 00000000 00000000 00000000<br />下面是一个将变量按位输出的程序，就是在写这个程序的时候发现的这个问题<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000"> std;<br /><br />template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> printbybit(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> ob)<br />{<br />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p_e</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">ob;<br />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">p_e</span><span style="COLOR: #000000">+</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(T)</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(;p</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">p_e;p</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">){<br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;i</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">){<br />            cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">(((</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">p)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">i))</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        }<br />    }<br />}<br /><br /><br /></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main()<br />{<br />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> x;<br />    x</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">65</span><span style="COLOR: #000000">;<br />    printbybit(x);<br />    cout.put(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> ch</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br />    printbybit(ch);<br />    cout.put(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br />    </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> lf</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br />    printbybit(lf);<br />    cout.put(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br />    system(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pause</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br /></span></div><img src ="http://www.cnitblog.com/luckydmz/aggbug/12401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-06-17 01:11 <a href="http://www.cnitblog.com/luckydmz/archive/2006/06/17/12401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代法</title><link>http://www.cnitblog.com/luckydmz/archive/2006/06/13/12159.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 13 Jun 2006 04:08:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/06/13/12159.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/12159.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/06/13/12159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/12159.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/12159.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">iostream</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">using</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">namespace</span>
				<span style="COLOR: #000000"> std;<br /><br /></span>
				<span style="COLOR: #0000ff">namespace</span>
				<span style="COLOR: #000000"> sqrt_nsp{<br />    </span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> n;<br />    </span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> sqrt_iter(</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> x){<br />        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> (x</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">sqrt_nsp::n</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">x)</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">;<br />    }<br />}<br /><br /><br /></span>
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000">
						<br />------迭代法------<br />前置条件<br />x=g(x)是f(x)=0的迭代函数<br />1)存在区间[a,b]，使当x属于[a, b]时，g(x)属于[a, b]<br />2)|g'(x)|恒小于1<br />3)x0属于[a,b]<br /><br />后置条件<br />返回f(x)=0在[a,b]上的根<br /></span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> iter_algo(</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> (</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">g)(</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000">), </span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> x0)<br />{<br />    </span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> t</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">g(x0);<br />    </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(t</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">x0</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">1e</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">6</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">||</span>
				<span style="COLOR: #000000">t</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">x0</span>
				<span style="COLOR: #000000">&lt;-</span>
				<span style="COLOR: #000000">1e</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">6</span>
				<span style="COLOR: #000000">){<br />        x0</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">t;<br />        t</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">g(x0);<br />    }<br />    </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> t;<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main ()<br />{<br />    sqrt_nsp::n</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">;<br />    printf(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">%lf\n</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">,iter_algo(</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">sqrt_nsp::sqrt_iter,</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">));<br />}<br /></span>
		</div>发觉库函数abs()丢失精度丢失的厉害。一开始iter_algo函数中while循环的条件是用abs表示的，输出结果的精度总是不够<img src ="http://www.cnitblog.com/luckydmz/aggbug/12159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-06-13 12:08 <a href="http://www.cnitblog.com/luckydmz/archive/2006/06/13/12159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二分逼近算法</title><link>http://www.cnitblog.com/luckydmz/archive/2006/06/11/12026.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Sun, 11 Jun 2006 05:25:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/06/11/12026.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/12026.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/06/11/12026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/12026.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/12026.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">前置条件,func(x)=0在区间[low,high]上有且只有一个根 <br /></span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">后置条件,返回 func(x)=0在区间[low,high]上的根，残量精确度小于0.000001 </span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> dichotomy(</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> low,</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> high,</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> (</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">func)(</span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000">))<br />{<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(func(low)</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">)<br />        swap(low,high);<br />    </span>
				<span style="COLOR: #0000ff">double</span>
				<span style="COLOR: #000000"> middle,t;<br />    </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000">(</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">){<br />        middle</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0.5</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">(low</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">high);<br />        t</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">func(middle);<br />        </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(t</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">1e</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">6</span>
				<span style="COLOR: #000000">)high</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">middle;<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(t</span>
				<span style="COLOR: #000000">&lt;-</span>
				<span style="COLOR: #000000">1e</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">6</span>
				<span style="COLOR: #000000">)low</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">middle;<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> middle;<br />    }<br />}</span>
		</div>
		<a href="http://my.opera.com/kyo_86/homes/files/%E4%BA%8C%E5%88%86%E9%80%BC%E8%BF%91%E7%AE%97%E6%B3%95.txt">二分逼近算法.txt</a>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/12026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-06-11 13:25 <a href="http://www.cnitblog.com/luckydmz/archive/2006/06/11/12026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数组的负整数下标，局部变量的空间分配</title><link>http://www.cnitblog.com/luckydmz/archive/2006/06/08/11857.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Thu, 08 Jun 2006 12:21:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/06/08/11857.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/11857.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/06/08/11857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/11857.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/11857.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">iostream</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">using</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">namespace</span>
				<span style="COLOR: #000000"> std;<br /><br /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main ()<br />{<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> a</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">,b[</span>
				<span style="COLOR: #000000">5</span>
				<span style="COLOR: #000000">]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">{</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000">3</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000">4</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000">5</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000">6</span>
				<span style="COLOR: #000000">},c</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">7</span>
				<span style="COLOR: #000000">;<br />    printf(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">%d %d %d\n</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">,b[</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">],b[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">],b[</span>
				<span style="COLOR: #000000">5</span>
				<span style="COLOR: #000000">]);<br />    printf(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">%d %d %d\n</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">b[</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">],</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">b[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">],</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">b[</span>
				<span style="COLOR: #000000">5</span>
				<span style="COLOR: #000000">]);<br />    </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000">system("pause");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /></span>
		</div>
		<p>在VC++6.0下得到输出<br />7 2 1<br />1245028 1245032 1245052<br /><br />在DEV-CPP4.9.9.0下得到输出<br /> 7 2 8<br /> 2293572 2293576 2293596<br />总结：<br />1.数组可以使用负整数下标。并且此时依然有<br />*(p+k)和p[k]等价，无论k是正整数还是负整数。<br /><br />2.对局部自动变量的空间分配是编译器决定的，不一定连续定义的变量空间就是连续的。<br /><br />PS：以前看到过一个例子，大概是</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main ()<br />{<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> i,a[</span>
				<span style="COLOR: #000000">10</span>
				<span style="COLOR: #000000">];<br />    </span>
				<span style="COLOR: #0000ff">for</span>
				<span style="COLOR: #000000">(i</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;i</span>
				<span style="COLOR: #000000">&lt;=</span>
				<span style="COLOR: #000000">10</span>
				<span style="COLOR: #000000">;i</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">){<br />        a[i]</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    }<br />}</span>
		</div>
		<br />
		<p>说这个循环因为对数组的越界访问会造成死循环，其实是不一定的，越界访问无庸置疑，但是不是造成死循环，是依赖编译器对变量的空间分配而决定的<br /></p>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/11857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-06-08 20:21 <a href="http://www.cnitblog.com/luckydmz/archive/2006/06/08/11857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串(char *)转整型(int)</title><link>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11265.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 30 May 2006 14:22:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11265.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/11265.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11265.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/11265.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/11265.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000">
						<br />函数原型:<br />int strtoi(const char *str,int base);<br /><br />描述:<br />将字符串转换为10进制无符号整数返回<br /><br />参数:<br />const char *str为需要转换的字符串,应由0-9和A-Z组成<br />int base字符串的进制(基数),应为2-36<br /><br />返回值:<br />返回传入字符串所代表的10进制无符号整数,如果参数错误无法转换返回-1<br /></span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> strtoi(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">str,</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">)<br />{<br />    </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> res</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">,t;<br />    </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p;<br />    </span>
				<span style="COLOR: #0000ff">for</span>
				<span style="COLOR: #000000">(p</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">str;</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p;p</span>
				<span style="COLOR: #000000">++</span>
				<span style="COLOR: #000000">){<br />        </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(isdigit(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p)){<br />            t</span>
				<span style="COLOR: #000000">=*</span>
				<span style="COLOR: #000000">p</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">;<br />        }<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(isupper(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p)){<br />            t</span>
				<span style="COLOR: #000000">=*</span>
				<span style="COLOR: #000000">p</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">A</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">10</span>
				<span style="COLOR: #000000">;<br />        }<br />        </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000"> {<br />            </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br />        }<br />        </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(t</span>
				<span style="COLOR: #000000">&gt;=</span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">)</span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br />        res</span>
				<span style="COLOR: #000000">*=</span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">;<br />        res</span>
				<span style="COLOR: #000000">+=</span>
				<span style="COLOR: #000000">t;<br />    }<br />    </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> res;<br />}<br /></span>
		</div>
		<a href="http://my.opera.com/kyo_86/homes/files/strtoi.txt">
				<font color="#002c99">strtoi.txt</font>
		</a>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/11265.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-05-30 22:22 <a href="http://www.cnitblog.com/luckydmz/archive/2006/05/30/11265.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>整型(int)转字符串(char *)类型</title><link>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11264.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 30 May 2006 14:19:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11264.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/11264.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/05/30/11264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/11264.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/11264.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">/*</span>
				<span style="COLOR: #008000">
						<br />函数原型:<br />char *itostr(int n, int base);<br /><br />描述:<br />传入十进制的n返回base进制的字符串，空间是函数内的static空间<br /><br />参数:<br />int n        将要转换的10进制整数<br />int base    需要返回的字符串的进制(基数),应为2-36<br /><br />返回值:<br />返回base进制的字符串，由阿拉伯数字和大写字母组成<br /></span>
				<span style="COLOR: #008000">*/</span>
				<span style="COLOR: #000000">
						<br />
						<br />
				</span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">itostr(</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> n, </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">)<br />{<br />    register </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p;<br />    register </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> minus;<br />    </span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000"> buf[</span>
				<span style="COLOR: #000000">36</span>
				<span style="COLOR: #000000">];<br />    <br />    p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">buf[</span>
				<span style="COLOR: #000000">36</span>
				<span style="COLOR: #000000">];<br />    </span>
				<span style="COLOR: #000000">*--</span>
				<span style="COLOR: #000000">p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (n </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">) {<br />        minus </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">;<br />        n </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">n;<br />    }<br />    </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000">
						<br />        minus </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (n </span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">)<br />        </span>
				<span style="COLOR: #000000">*--</span>
				<span style="COLOR: #000000">p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">;<br />    </span>
				<span style="COLOR: #0000ff">else</span>
				<span style="COLOR: #000000">
						<br />        </span>
				<span style="COLOR: #0000ff">while</span>
				<span style="COLOR: #000000"> (n </span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">) {<br />            </span>
				<span style="COLOR: #000000">*--</span>
				<span style="COLOR: #000000">p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">[n </span>
				<span style="COLOR: #000000">%</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">];<br />            n </span>
				<span style="COLOR: #000000">/=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">base</span>
				<span style="COLOR: #000000">;<br />        }<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> (minus)<br />        </span>
				<span style="COLOR: #000000">*--</span>
				<span style="COLOR: #000000">p </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">; <br />    </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> p;<br />}<br /></span>
		</div>
		<br />
		<a href="http://my.opera.com/kyo_86/homes/files/itostr.txt">
				<font color="#002c99">itostr.txt</font>
		</a>
<img src ="http://www.cnitblog.com/luckydmz/aggbug/11264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-05-30 22:19 <a href="http://www.cnitblog.com/luckydmz/archive/2006/05/30/11264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>保守地使用inline </title><link>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10610.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 16 May 2006 12:28:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10610.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/10610.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/10610.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/10610.html</trackback:ping><description><![CDATA[<p>作者：ZDNetChina<br />2004-02-0511:19AM&nbsp;</p>
		<p>在早期的C++中，inline关键字通常被认为是劝说程序员使用setters和getters代替直接访问数据成员的一种方式。今天，大多数的编译器都比一般程序员更加清楚什么函数更适合inlining。此外，inline的使用可以导致繁重的维护问题，敏感的bugs和无用功。</p>
		<p>一个典型的函数由一行代码组成。定义它inline在开始的时候感觉很合理：</p>
		<p>classFile<br />{<br />public:<br />intget_descriptor()const;<br />//..<br />private:<br />int_fd;<br />//..<br />};</p>
		<p>inlineintFile::get_descriptor()const<br />{return_fd;}//fine,aslimfunctionbody</p>
		<p>考虑到由于设计的改变，移动到新的系统或者OS中等等，get_descriptor()现在包含的15行代码。很显然，不能再定义inline。那么，维护者会记得将inline从这个函数的定义中移动吗？</p>
		<p>
				<strong>Inline和静态连接</strong>
		</p>
		<p>另外一个问题在被代码库使用的inline函数中浮现。许多程序库使用的是静态连接，库会在没有终端用户改变他们的程序的情况下进行代码改变。但是，如果一个inline函数的改变将不能维护二进制文件的兼容性，在这种情况下，用户必须重新编译他们的代码。就是说，例如一个exe使用到了一个lib，lib在保持所有接口含义的情况下改变了实现方法，如果应用的代码没有任何变化那么只需要用新的lib重新link即可，但是如果lib中有inline函数而inline函数发生了变化，那么exe不得不重新编译，这有悖lib的意义，而且容易引起因编译器检查错误而遗漏重编。</p>
		<p>
				<strong>Inline使用规则</strong>
		</p>
		<p>使用inline的危险超过了它的好处，如果你的代码需要被优化，通常使用专业的模型来优化他们。使用inline仅仅是代码部分需要被优化的时候，并且你发觉只有inline才可以改变它们的性能时才使用。除此之外，避免使用inline。</p>
		<p>本文作者：DannyKaley是一个有着14年丰富经验的系统分析师和软件工程师。他擅长C++和面向对象的程序设计。</p><img src ="http://www.cnitblog.com/luckydmz/aggbug/10610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-05-16 20:28 <a href="http://www.cnitblog.com/luckydmz/archive/2006/05/16/10610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>避免使用 protected 类型的数据成员</title><link>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10609.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Tue, 16 May 2006 12:16:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10609.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/10609.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/05/16/10609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/10609.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/10609.html</trackback:ping><description><![CDATA[作者： Builder.com<br />2005-01-10 02:2 PM<br />Protected 类型数据成员的问题<br />当基类的实现发生变化时，能够访问基类 protected 类型数据成员的派生类也需要修改。这叫做耦合，耦合是面向对象的设计方法绝对需要避免的东西。<br />你应该避免使用 protected 类型的数据成员，因为他们会造成对封装的一个错误的理解。相反，将数据成员声明为 private 类型并定义相应的成员函数来访问它们是必要的。通过使用这种方法，基类设计上的变化就不会影响其它类。此外，它也不会引诱程序员使用继承获得对数据成员的直接访问。最重要的是，基类的所有者可以自由地改变基类的实现，同时又保持原有接口不变，而不至引起检查所有的代码。<img src ="http://www.cnitblog.com/luckydmz/aggbug/10609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-05-16 20:16 <a href="http://www.cnitblog.com/luckydmz/archive/2006/05/16/10609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于运行时类型识别typeid</title><link>http://www.cnitblog.com/luckydmz/archive/2006/05/07/10161.html</link><dc:creator>魔のkyo</dc:creator><author>魔のkyo</author><pubDate>Sun, 07 May 2006 05:28:00 GMT</pubDate><guid>http://www.cnitblog.com/luckydmz/archive/2006/05/07/10161.html</guid><wfw:comment>http://www.cnitblog.com/luckydmz/comments/10161.html</wfw:comment><comments>http://www.cnitblog.com/luckydmz/archive/2006/05/07/10161.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/luckydmz/comments/commentRss/10161.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luckydmz/services/trackbacks/10161.html</trackback:ping><description><![CDATA[
		<p>在程序中，当我们对多态类的基类指针使用typeid，就可以在运行时确定指针指向对象的实际类型，并输出对象类型的名字。</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">cstdlib</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">iostream</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">typeinfo</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">using</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">namespace</span>
				<span style="COLOR: #000000"> std;<br /><br /></span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> B{<br /></span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">:<br />    </span>
				<span style="COLOR: #0000ff">virtual</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> fun(){}<br />};<br /><br /></span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> D:</span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> B{<br /></span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">:<br />    </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> fun(){}<br />};<br /><br /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> main()<br />{<br />    B </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p;<br />    D ob;<br />    p</span>
				<span style="COLOR: #000000">=&amp;</span>
				<span style="COLOR: #000000">ob;<br />    cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">typeid(*p).name()=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">typeid(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p).name()</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(typeid(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">p)</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">typeid(D))<br />        cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">typeid(*p)==typeid(D)</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />    cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">typeid(p).name()=</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">typeid(p).name()</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000">(typeid(p)</span>
				<span style="COLOR: #000000">==</span>
				<span style="COLOR: #000000">typeid(B</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">))<br />        cout</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">typeid(p)==typeid(B*)</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">&lt;&lt;</span>
				<span style="COLOR: #000000">endl;<br />    system(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">pause</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />    </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">;<br />}<br /></span>
		</div>
		<br />这段code在VC++6.0中编译时，提示如下<br />warning C4541: 'typeid' used on polymorphic type 'class B' with /GR-; unpredictable behavior may result<br />编译后运行时错误。不知是不是此版本的VC++不符合C++标准？<br /><br />在Devcpp（g++）中编译运行得到的结果是<br />typeid(*p).name()=1D<br />typeid(*p)==typeid(D)<br />typeid(p).name()=P1B<br />typeid(p)==typeid(B*)<br />说明用typeid作用于*p得到的的确是D类型，而用typeid作用于p得到的依然是B类的指针类型<br /><br />如果typeid被作用于非多态类指针，那么我们得到的是指针被声明的类型，也就是说，此时typeid并不会返回指针所指向对象的实际类型。<br />如果将class B中的virtual去掉，在编译运行得到的结果是<br />typeid(*p).name()=1B<br />typeid(p).name()=P1B<br />typeid(p)==typeid(B*)<br /><br />由此可见，在任何时刻都可以用基类指针指向派生类对象，而用typeid(*p)确定p指向的对象时，只当基类为多态类时才能真正确定p在运行时指向的实际类型。<img src ="http://www.cnitblog.com/luckydmz/aggbug/10161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luckydmz/" target="_blank">魔のkyo</a> 2006-05-07 13:28 <a href="http://www.cnitblog.com/luckydmz/archive/2006/05/07/10161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>