﻿<?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>C++博客-战魂小筑-随笔分类-操作系统</title><link>http://www.cppblog.com/sunicdavy/category/12573.html</link><description>跨平台通用游戏服务器架构, 脚本及嵌入技术, 3D引擎&amp;Shader代码生成, 开发工具技巧 email: 20998333#qq.com</description><language>zh-cn</language><lastBuildDate>Fri, 20 Apr 2012 05:14:36 GMT</lastBuildDate><pubDate>Fri, 20 Apr 2012 05:14:36 GMT</pubDate><ttl>60</ttl><item><title>让C/C++程序一次编译可以发布到多版本Linux之上</title><link>http://www.cppblog.com/sunicdavy/archive/2012/04/20/172108.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 20 Apr 2012 03:35:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/04/20/172108.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/172108.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/04/20/172108.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/172108.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/172108.html</trackback:ping><description><![CDATA[<p>最近页游开放平台比较多, 每个平台要求的Linux版本各不相同, 这给开发人员部署服务器带来了很大的困难. 在本机Linux编译的程序,发布时即便将依赖的so附带到目标Linux环境,仍然会碰到依赖及版本问题,例如:</p> <p><font face="Lucida Console">[root@localhost bin]# ldd wkcenter <br /><font color="#ff0000">./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./wkcenter)<br />./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./wkcenter)<br />./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./wkcenter)<br />./wkcenter: /lib/libc.so.6: version `GLIBC_2.9' not found (required by ./wkcenter)<br />./wkcenter: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./wkcenter)<br />./wkcenter: /lib/libc.so.6: version `GLIBC_2.8' not found (required by ./wkcenter)<br />./wkcenter: /lib/libc.so.6: version `GLIBC_2.11' not found (required by ./wkcenter)</font><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; linux-gate.so.1 =&gt;&nbsp; (0xffffe000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liblog4cpp.so.4 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libprotobuf.so.7 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libboost_filesystem.so.1.48.0 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libboost_system.so.1.48.0 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libboost_thread.so.1.48.0 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libboost_program_options.so.1.48.0 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libunwind-x86.so.7 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libluabind.so.0.9.0 =&gt; not found<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libstdc++.so.6 =&gt; /usr/lib/libstdc++.so.6 (0x008ae000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libm.so.6 =&gt; /lib/libm.so.6 (0x0044b000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libgcc_s.so.1 =&gt; /lib/libgcc_s.so.1 (0x00476000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libc.so.6 =&gt; /lib/libc.so.6 (0x002c1000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libpthread.so.0 =&gt; /lib/libpthread.so.0 (0x0041d000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; librt.so.1 =&gt; /lib/librt.so.1 (0x00440000)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /lib/ld-linux.so.2 (0x002a2000)</font><br /></p> <p>上面红字部分表示glibc及glibcxx库依赖不正确. 本人使用的Linux编译版本为Mint 11(基于Ubuntu), 一般Ubuntu发行版的glibc配备非常高. 但是上文中的发布的Linux版本为CentOS 5.8</p> <p>使用/lib/libc.so.6 查看libc版本为2.5, 远远低于开发环境的2.11</p> <p><font face="Lucida Console">GNU C Library stable release version <font color="#ff0000">2.5</font>, by Roland McGrath et al.<br />Copyright (C) 2006 Free Software Foundation, Inc.<br />This is free software; see the source for copying conditions.<br />There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A<br />PARTICULAR PURPOSE.<br />Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-51).<br />Compiled on a Linux 2.6.9 system on 2012-02-21.<br />Available extensions:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The C stubs add-on version 2.1.2.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; crypt add-on version 2.1 by Michael Glad and others<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GNU Libidn by Simon Josefsson<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GNU libio by Per Bothner<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Native POSIX Threads Library by Ulrich Drepper et al<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BIND-8.2.3-T5B<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RT using linux kernel aio<br />Thread-local storage support included.<br />For bug reporting instructions, please see:<br />&lt;</font><a href="http://www.gnu.org/software/libc/bugs.html"><font face="Lucida Console">http://www.gnu.org/software/libc/bugs.html</font></a><font face="Lucida Console">&gt;.</font></p> <p><font face="Lucida Console">由于Linux操作系统的特有elf加载顺序. (可以参考<a href="http://www.iteedu.com/os/linux/mklinuxdiary/ch4mksystem/4.php">此文</a>). 虽然可以很大程度上解决Windows早期版本的dll hell问题, 但是给部署带来了很大难度</font></p> <p><font face="Lucida Console">一般常见的解决方法是, 找到一个与目标Linux版本及glibc版本一致的Linux, 将代码及依赖包放在之上编译, 完成后再发布.这种方法与Linux下常见软件安装方法类似. 但是对于商用服务器部署步骤来说未免繁琐, 安全性低.</font></p> <p>还有一种方法,使用静态链接. 将所有可执行文件文件依赖的静态库, 系统库,全部静态链接到可执行文件中,可以一次性解决这个问题</p> <p>步骤:</p> <p>&nbsp;&nbsp;&nbsp; 1. 在gcc链接命令行中添加-static -static-libgcc -static-libstdc++</p> <p>&nbsp;&nbsp;&nbsp; 2. 将第三方依赖库打开静态链接开关, 将原来链接.so的库,全改为链接.a</p> <p>&nbsp;&nbsp;&nbsp; 3. gcc对链接库顺序很敏感, 链接库顺序需要按照从前至后为:&nbsp; 项目产生的静态库 &gt; 第三方库静态库 &gt; 系统静态库</p> <p>&nbsp;&nbsp;&nbsp; 4. 链接时, 若有未解决的symbol, 可以尝试在最后添加-lpthread及-lrt解决</p> <p>&nbsp;&nbsp;&nbsp; </p> <p>在发布版本Linux上运行可能遇到的问题:</p> <p><font face="Lucida Console">terminate called after throwing an instance of 'std::runtime_error'</font> </p><p><font face="Lucida Console">what(): locale::facet::_S_create_c_locale name not valid</font> </p><p>解决方法: 执行之前运行export LC_ALL="C"  </p><img src ="http://www.cppblog.com/sunicdavy/aggbug/172108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-04-20 11:35 <a href="http://www.cppblog.com/sunicdavy/archive/2012/04/20/172108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux服务自动安装卸载部署脚本</title><link>http://www.cppblog.com/sunicdavy/archive/2012/04/12/171026.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 12 Apr 2012 01:33:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/04/12/171026.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/171026.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/04/12/171026.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/171026.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/171026.html</trackback:ping><description><![CDATA[<pre class="csharpcode"><span class="rem">#!/bin/bash</span>
<span class="rem"># chkconfig: 3 3 1</span>
<span class="rem"># description: svclauncher</span></pre><pre class="csharpcode">ServicePath=/usr/<span class="kwrd">local</span>/bin

ServiceList=(
<span class="str">"wkcenterd --toc /home/davy/dev/kaze/Config/CenterService.toc --logfile /tmp/centerd.log"</span>
<span class="str">"wkagentd --toc /home/davy/dev/kaze/Config/AgentService.toc --logfile /tmp/agentd.log"</span>
)

StartAll()
{
    <span class="kwrd">for</span>((i = 0;i&lt;${<span class="rem">#ServiceList[*]};i=i+1))</span>
    do

     echo <span class="str">"start:"</span> $ServicePath/${ServiceList[i]}
     $ServicePath/${ServiceList[i]} &gt; /dev/null &amp;

    done
}

StopAll()
{
    <span class="kwrd">for</span>((i = 0;i&lt;${<span class="rem">#ServiceList[*]};i=i+1))</span>
    do

     echo <span class="str">"stop:"</span> $ServicePath/${ServiceList[i]}
     svcname=`echo ${ServiceList[i]} | awk <span class="str">'{print $1}'</span>`
     killall $svcname &gt; /dev/null

    done
}

RestartAll()
{
    StopAll
    StartAll
}


InstallService()
{
    svcname=`basename $0`
    chmod +x $svcname
    cp $svcname /etc/init.d
    ln /etc/init.d/$svcname /etc/rc3.d/S03$svcname
    ln /etc/init.d/$svcname /etc/rc0.d/K03$svcname
    chkconfig --add $svcname
    chkconfig $svcname on
    chkconfig --list | grep $svcname
}

UninstallService()
{
    svcname=`basename $0`
    chkconfig --del $svcname
    rm -f /etc/init.d/$svcname
    rm -f /etc/rc3.d/S03$svcname
    rm -f /etc/rc3.d/K03$svcname
}



case <span class="str">"$1"</span> <span class="kwrd">in</span>
    start)
    StartAll
    ;;
    stop)
    StopAll
    ;;
    restart)
    RestartAll
    ;;
    install)
    InstallService
    ;;
    uninstall)
    UninstallService
    ;;
    *)
           echo <span class="str">"Usage: service $EXEC {install|start|stop|restart|uninst}"</span>
       exit 1
esac
 
exit $? </pre>
<p>
<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></p><img src ="http://www.cppblog.com/sunicdavy/aggbug/171026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-04-12 09:33 <a href="http://www.cppblog.com/sunicdavy/archive/2012/04/12/171026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux在VMware中网络设置</title><link>http://www.cppblog.com/sunicdavy/archive/2012/02/04/164934.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Sat, 04 Feb 2012 03:41:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2012/02/04/164934.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/164934.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2012/02/04/164934.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/164934.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/164934.html</trackback:ping><description><![CDATA[<p>这里使用的是Ubuntu的最流行发行版Mint, 其他版本类似</p> <p>以下将虚拟机内系统叫Guest, 运行VMWare的系统叫Host</p> <p>将VMWare的网络方式设为Bridge模式. 注意Host-Only模式只能与Host连接,局域网的机器及互联网机器无法访问</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb_2.png" width="306" height="276"></a></p> <p>在Guest的网络设置中,将IP设置为与Host在一个局域网网段的IP, 设置DNS</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb_1.png" width="402" height="292"></a></p> <p>关闭Guest系统</p> <p>接下来将Host的可以上网的连接添加共享,并连接到VMNet1</p> <p><a href="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/sunicdavy/Windows-Live-Writer/Linux-VMware_A07B/image_thumb.png" width="599" height="232"></a></p> <p>进入Guest系统, 测试上网</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/164934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2012-02-04 11:41 <a href="http://www.cppblog.com/sunicdavy/archive/2012/02/04/164934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设置进程路径为启动路径</title><link>http://www.cppblog.com/sunicdavy/archive/2011/12/01/161272.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 01 Dec 2011 03:28:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/12/01/161272.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/161272.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/12/01/161272.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/161272.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/161272.html</trackback:ping><description><![CDATA[<div class="csharpcode"><pre>   VC有个让新手抓狂的地方, 把工程路径作为调试模式时的进程当前目录. </pre></div>
<p>估计很多新手因为打不开文件而耗费大量的时间,甚至放弃</p>
<p>以前使用纯Windows方式解决这种问题:</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>#include &lt;Shlwapi.h&gt;</pre><pre><span class="lnum">   2:  </span>#include &lt;shlobj.h&gt;</pre><pre class="alt"><span class="lnum">   3:  </span>&nbsp;</pre><pre><span class="lnum">   4:  </span><span class="preproc">#pragma</span> comment(lib,<span class="str">"shlwapi.lib"</span>)</pre><pre class="alt"><span class="lnum">   5:  </span>&nbsp;</pre><pre><span class="lnum">   6:  </span>wchar_t exename[MAX_PATH];</pre><pre class="alt"><span class="lnum">   7:  </span>::GetModuleFileName(NULL,exename,MAX_PATH);</pre><pre><span class="lnum">   8:  </span>::PathRemoveFileSpec( exename );</pre><pre class="alt"><span class="lnum">   9:  </span>::SetCurrentDirectory( exename );</pre></div>
<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>

<p></p>
<p> 需要跨平台时,可以这样写:</p>
<div class="csharpcode"><pre class="alt"><span class="lnum">   1:  </span>#include &lt;direct.h&gt;</pre><pre><span class="lnum">   2:  </span>#include &lt;boost/filesystem.hpp&gt;</pre><pre class="alt"><span class="lnum">   3:  </span>&nbsp;</pre><pre><span class="lnum">   4:  </span><span class="kwrd">int</span> main(<span class="kwrd">int</span> argc, <span class="kwrd">char</span>* argv[])</pre><pre class="alt"><span class="lnum">   5:  </span>{    </pre><pre><span class="lnum">   6:  </span>    _chdir( boost::filesystem::path( argv[0] ).remove_filename().<span class="kwrd">string</span>().c_str() );        </pre><pre class="alt"><span class="lnum">   7:  </span>}</pre></div>
<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>

<p></p>&nbsp;&nbsp;&nbsp;&nbsp; 被Windows惯坏了, 到处找Linux或者boost版本的GetModuleFileName, 结果忘记了当年c语言课上教的命令行传入参数...<img src ="http://www.cppblog.com/sunicdavy/aggbug/161272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-12-01 11:28 <a href="http://www.cppblog.com/sunicdavy/archive/2011/12/01/161272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC中使用SetThreadName引起的线程死锁</title><link>http://www.cppblog.com/sunicdavy/archive/2011/10/12/158109.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 12 Oct 2011 01:50:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2011/10/12/158109.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/158109.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2011/10/12/158109.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/158109.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/158109.html</trackback:ping><description><![CDATA[<p>我在工程里使用以下函数给线程设置一个方便调试的名称</p> <div class="csharpcode"><pre class="alt">    typedef <span class="kwrd">struct</span> tagTHREADNAME_INFO</pre><pre>    {</pre><pre class="alt">        DWORD dwType;        <span class="rem">// must be 0x1000</span></pre><pre>        LPCSTR szName;        <span class="rem">// pointer to name (in user addr space)</span></pre><pre class="alt">        DWORD dwThreadID;    <span class="rem">// thread ID (-1=caller thread)</span></pre><pre>        DWORD dwFlags;        <span class="rem">// reserved for future use, must be zero</span></pre><pre class="alt">    } THREADNAME_INFO;</pre><pre>&nbsp;</pre><pre class="alt">    <span class="kwrd">void</span> SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )</pre><pre>    {</pre><pre class="alt">        THREADNAME_INFO info;</pre><pre>        info.dwType = 0x1000;</pre><pre class="alt">        info.szName = szThreadName;</pre><pre>        info.dwThreadID = dwThreadID;</pre><pre class="alt">        info.dwFlags = 0;</pre><pre>&nbsp;</pre><pre class="alt">          <span class="rem">// Visit http://www.cppblog.com/sunicdavy for original article</span></pre><pre>        __try</pre><pre class="alt">        {</pre><pre>            RaiseException( 0x406D1388, 0, <span class="kwrd">sizeof</span>(info)/<span class="kwrd">sizeof</span>(DWORD), (DWORD*)&amp;info );</pre><pre class="alt">        }</pre><pre>        __except(EXCEPTION_CONTINUE_EXECUTION)</pre><pre class="alt">        {</pre><pre>            <span class="kwrd">int</span> a =1;</pre><pre class="alt">        }</pre><pre>    }</pre></div>
<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>

<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>

<p>使用期间一直正常. 随着工程需求变化,我需要<strong>频繁的</strong>将一个被命名的线程创建工作一段时间后<strong>马上结束释放资源并重新创建</strong>,出现了死锁问题</p>
<p>死锁总是发生在主线程的Sleep或者是SetEvent两个WindowsAPI函数. 而且仅仅在Visual Studio 2008里调试时会发生死锁,脱离调试环境一切正常.</p>
<p>我开始打日志调试, 结果发现死锁前能够正常创建线程,但是线程函数根本没有调用进入.之后就在主线程Sleep处死锁了.</p>
<p>由于SetThreadName没有使用正规的API接口,而是使用抛异常方式, 而且线程名称应该只在Visual Studio IDE中才能显示, MSDN对RaiseException的描述里也有说明可以使用<b>WaitForDebugEvent</b>接收应用程序抛得异常.因此可以推断是SetThreadName造成的问题. 屏蔽SetThreadName,测试通过</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/158109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2011-10-12 09:50 <a href="http://www.cppblog.com/sunicdavy/archive/2011/10/12/158109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>恶心的GetPrivateProfileString</title><link>http://www.cppblog.com/sunicdavy/archive/2010/09/02/125606.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Thu, 02 Sep 2010 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/09/02/125606.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/125606.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/09/02/125606.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/125606.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/125606.html</trackback:ping><description><![CDATA[<p>很久没有用WindowsAPI来读取INI，在公司写服务器逻辑需要用到，拿来试了下。</p> <p>记得很早以前就用过GetPrivateProfile*系的INI读取函数，有一个问题很烦:ini的文件路径必须是绝对路径，否则即便工作路径是设置正确的，也是无法读取到ini文件。以前有查过，说是内部搜索路径的问题。默认是在system32去找。4，5年前的处理方法就是把绝对路径拿过来和当前路径组合后传给GetPrivateProfile*系API。</p> <p>之后，我自己一直是用自己封装的文本解析类来读取ini，很久没碰这个API，也就没有路径烦恼</p> <p>今天再次碰到，故询问了下其他人有没有什么好的方法：</p> <p><strong>只需要将路径改为当前路径标识即可，即：</strong></p> <p><strong>setting.ini&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp;&nbsp; ./setting.ini</strong></p> <p><strong></strong>&nbsp;</p> <p>再次诅咒这个恶心的API</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/125606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-09-02 10:11 <a href="http://www.cppblog.com/sunicdavy/archive/2010/09/02/125606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>修改线程名称,并在VC调试器中显示</title><link>http://www.cppblog.com/sunicdavy/archive/2010/05/04/114342.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 04 May 2010 07:28:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/05/04/114342.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/114342.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/05/04/114342.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/114342.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/114342.html</trackback:ping><description><![CDATA[<div class="csharpcode"><pre class="alt"><span class="preproc">#define</span> MS_VC_EXCEPTION 0x406d1388</pre><pre>&nbsp;</pre><pre class="alt">typedef <span class="kwrd">struct</span> tagTHREADNAME_INFO</pre><pre>{</pre><pre class="alt">    DWORD dwType;        <span class="rem">// must be 0x1000</span></pre><pre>    LPCSTR szName;       <span class="rem">// pointer to name (in same addr space)</span></pre><pre class="alt">    DWORD dwThreadID;    <span class="rem">// thread ID (-1 caller thread)</span></pre><pre>    DWORD dwFlags;       <span class="rem">// reserved for future use, most be zero</span></pre><pre class="alt">} THREADNAME_INFO;</pre><pre>&nbsp;</pre><pre class="alt"><span class="kwrd">void</span> SetThreadName(DWORD dwThreadID, LPCTSTR szThreadName)</pre><pre>{</pre><pre class="alt">    THREADNAME_INFO info;</pre><pre>    info.dwType = 0x1000;</pre><pre class="alt">    info.szName = szThreadName;</pre><pre>    info.dwThreadID = dwThreadID;</pre><pre class="alt">    info.dwFlags = 0;</pre><pre>&nbsp;</pre><pre class="alt">    __try</pre><pre>    {</pre><pre class="alt">        RaiseException(MS_VC_EXCEPTION, 0, <span class="kwrd">sizeof</span>(info) / <span class="kwrd">sizeof</span>(DWORD),</pre><pre>(DWORD *)&amp;info);</pre><pre class="alt">    }</pre><pre>    except (EXCEPTION_CONTINUE_EXECUTION)</pre><pre class="alt">    {</pre><pre>    }</pre><pre class="alt">}</pre></div>
<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>

<p>&nbsp;</p>
<p>线程名称限制在9个ANSI字符内,调用这个函数后,将触发一个调试器异常,VC调试器将会把字符串设置为线程名称,并在调试器中显示</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/114342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-05-04 15:28 <a href="http://www.cppblog.com/sunicdavy/archive/2010/05/04/114342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows里的一个有趣的地方</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/16/112778.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 16 Apr 2010 09:20:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/16/112778.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/112778.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/16/112778.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/112778.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/112778.html</trackback:ping><description><![CDATA[<p> 在Windows XP下, 在任何磁盘里,创建一个文件,再复制粘贴,就会生成一个新的拷贝.文件名中有个词叫:"复件"</p> <p>但是感觉这个词貌似是学多了英语后的人硬拼出来的,时间长了,大家习惯了这个叫法,这个词也就出来了.</p> <p>在Windows Vista或者Windows 7里,这个词变成了 "副本", 估计是微软也发现"复件"这个词不是很正规或者让人接受而换的</p> <p>:)</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/112778.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-16 17:20 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/16/112778.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows XP 2升级到SP3所带来的麻烦</title><link>http://www.cppblog.com/sunicdavy/archive/2010/04/14/112565.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Wed, 14 Apr 2010 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2010/04/14/112565.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/112565.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2010/04/14/112565.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/112565.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/112565.html</trackback:ping><description><![CDATA[<p>从Windows XP SP2通过Windows Updates 的SP3推送更新到SP3并不是真正意义上的SP3. 至少发现有以下兼容问题:</p> <p>1. RenderMonkey 1.82 在这种升级版本下会启动会报MSXML错误</p> <p>2. VS2010 安装完成后, C#和WPF工程都无法正常创建,打开vs2008及老的sln,project都会出现卡死,甚至崩溃的错误. 估计也是MSXML的问题</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>解决方法:安装Windows 更高版本或者直接使用原生Windows SP3</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/112565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2010-04-14 15:53 <a href="http://www.cppblog.com/sunicdavy/archive/2010/04/14/112565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让Windows7快速启动资源管理器不进入库</title><link>http://www.cppblog.com/sunicdavy/archive/2009/12/25/104091.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Fri, 25 Dec 2009 15:17:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2009/12/25/104091.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/104091.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2009/12/25/104091.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/104091.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/104091.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 前不久将自己2005年的古董笔记本从Windows7换回WindowsXP，马上感觉到了什么叫硬盘IO。即便是移动硬盘间的拷贝，想要顺畅的回复QQ消息，输入法弹出都变得异常慢。因此还是决定换回Windows7，这次真正感觉到新操作系统在系统资源上的算法进步。</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Windows7默认点击快速启动中的资源管理器弹出的不是“我的电脑”，而是恶心的“库”。程序员的电脑都是井井有条的，因此“库”这种东西只会让每次重装系统后大喊后悔。有一个简单的方法可以让其直接进入“我的电脑”</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 右键点击快速启动的图标，在弹出的菜单从下往上的“Windows资源管理器”上点击右键，点击属性。，在“快捷方式”标签的目标“%windir%\explorer.exe”后加入一个空格和一个逗号，如“%windir%\explorer.exe ,”（没有双引号），即可。</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/104091.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2009-12-25 23:17 <a href="http://www.cppblog.com/sunicdavy/archive/2009/12/25/104091.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Windows 7 工作</title><link>http://www.cppblog.com/sunicdavy/archive/2009/10/27/99553.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Tue, 27 Oct 2009 02:32:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2009/10/27/99553.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/99553.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2009/10/27/99553.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/99553.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/99553.html</trackback:ping><description><![CDATA[
<p>&nbsp;&nbsp;&nbsp; Windows 7 已经发布了，不过我在几个月前已经开始使用。实在是不喜欢Vista，因此直接跳过使用了win7.总体感觉还是不错，现在来说下Windows 7的使用感觉。</p> <p>&nbsp;&nbsp;&nbsp; 如果用过Vista，那么Windows 7只能说是方便了，而不能说是漂亮了。但是如果直接从XP过来，那么就会感觉Windows 7非常漂亮。Windows 7的驱动兼容性很好。我家里2005年的BenQ本子所有驱动，包括读卡器都可以通过自动更新找到。另外，程序兼容性也没有那么夸张，基本上大部分的程序都可以兼容，特别是兼容Vista的，基本都可以跑在Windows 7下。即便不能兼容的程序，就像当年98/2000到xp一样，调节下兼容性就可以了。</p> <p>&nbsp;&nbsp;&nbsp; 如果你使用Windows 7来工作，那么恭喜你，Windows 7的使用效率是很高的。还在XP的3大页开始菜单中找Visual Studio么？还在调节控制面板到98时代的经典菜单，一个一个的找防火墙么？ 只需要在开始菜单里输入你要找的东西，很快就可以找到这些功能。</p> <p>&nbsp;&nbsp;&nbsp; 虽然Windows 7的jumplist是抄袭MacOS，但转过来想想，Windows本身何不是从Mac抄袭过来的呢？除了jumplist，还有一个功能也许一般很难被发现：用鼠标中键点击任务栏，可以启动这个程序的新实例。这个对于Chrome这种多进程浏览器来说实在是很方便的事情。</p> <p>&nbsp;&nbsp;&nbsp; 工作中，公司还在使用VS2005，但是第一次使用，不小心习惯性的调整到了兼容XP模式，结果不管是IDE还是编译器，一直报错。后来查过网站后，才发现，VS2005绝对不要在Windows 7下打开兼容性。</p> <p>&nbsp;&nbsp;&nbsp; 另外，很多VPN由于Vista以上系统的安全性问题，都不能在Windows 7下使用了。另外让公司配机器又很麻烦，这时最好的方法就是装一台虚拟机：VMWare+ xp，20分钟装完就可以使用了。比Windows 7自带的那个要求低多了，而且还可以在里面跑DX一类图形程序，比远程桌面方便多了</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/99553.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2009-10-27 10:32 <a href="http://www.cppblog.com/sunicdavy/archive/2009/10/27/99553.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 7 感叹</title><link>http://www.cppblog.com/sunicdavy/archive/2009/08/17/93564.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 17 Aug 2009 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2009/08/17/93564.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/93564.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2009/08/17/93564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/93564.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/93564.html</trackback:ping><description><![CDATA[
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 安装Windows 7 RTM 7600.16385。从XP，Vista到7，Windows系统一直保持着清一色的无聊，纯本地应用。最多只是美化界面而已，虽然有部分细节修改，但是打开文件通用对话框被各种shell做的臃肿不堪，因此，xp仍然是王道</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很多人喜欢将东西放在桌面，这倒也符合工作习惯，但是经过长时间后，桌面会变得凌乱不堪，虽然Windows过段时间会有自动桌面清理，但也仅仅是将文件放置在桌面的一个文件夹中。为什么不学下qq mail里的中转站，7天后都使用后自动清理？而且win2000里的动态桌面到了后面的版本就取消了？为什么不能这些功能放到web上？这样做对于家用确实会很方便</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; 还有就是最严重的Windows Media Player，将一文件夹拖入居然不能播放这个文件夹。建立好一个播放列表后，仍然不能拖入文件夹，真不知道MS的开发者平时用不用这个软件。。</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/93564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2009-08-17 10:46 <a href="http://www.cppblog.com/sunicdavy/archive/2009/08/17/93564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>由Android想到的OS manifest机制</title><link>http://www.cppblog.com/sunicdavy/archive/2009/08/10/92827.html</link><dc:creator>战魂小筑</dc:creator><author>战魂小筑</author><pubDate>Mon, 10 Aug 2009 09:57:00 GMT</pubDate><guid>http://www.cppblog.com/sunicdavy/archive/2009/08/10/92827.html</guid><wfw:comment>http://www.cppblog.com/sunicdavy/comments/92827.html</wfw:comment><comments>http://www.cppblog.com/sunicdavy/archive/2009/08/10/92827.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/sunicdavy/comments/commentRss/92827.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/sunicdavy/services/trackbacks/92827.html</trackback:ping><description><![CDATA[
<p>&nbsp;&nbsp;&nbsp;&nbsp; 病毒，说白了就是可以做任意事情的破坏性程序，这不算什么，大不了只是一个地方黑社会。<br>木马，简而言之就是只要给我联网，我就可以黑掉你<br>&nbsp;&nbsp;&nbsp;&nbsp; 微软已经把Windows系统给做烂了。exe可以在管理员权限下任意运行，从而导致病毒木马的泛滥。其实转过头来看很多手机操作系统，例如Android，也是使用WindowsXP后为exe引入的manifest概念，但是却从根本上解决了很多安全性弊病<br>&nbsp;&nbsp;&nbsp;&nbsp; Android中，每个运行入口，必须有一个manifest来让OS知道你这个程序需要做什么，由OS为你配备网络，磁盘读取等等需求。<br>&nbsp;&nbsp;&nbsp;&nbsp; 如果将病毒的访问权限降低，例如跑在虚拟机里面，病毒就没有毒了，木马即便能获取机密信息，也发不出了。<br>而Windows呢，由于本身概念设计的缺陷，一个程序写好后拥有完全权限进行访问，OS并不了解一个程序能做什么，只有当这个程序调用API时才知道，但有时也决定于调用时的数据，比如只有打开系统盘文件才受到限制。于是乎，很多商家看到了money，使用API HOOK，rootkit等等底层钩子来模拟出了一套超级虚拟机，妄想用一个软件控制住另外一个软件的访问，简直是痴人说梦。<br>&nbsp;&nbsp;&nbsp;&nbsp; 也许你会说，UNIX/Linux不是在这方面做的很好么？引入用户及权限，默认不在管理员下运行。这点Windows也做了，不过很好么？看看UAC，Linux下运行也很麻烦。&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; 试想下，如果Windows也拥有和Android一样的manifest机制，那么病毒扫描也就仅仅需要检查manifest文件就可以。对于老的程序，可以开启一个权限自动检查模式进行运行，一段时间后，自动为这个老程序生成新的manifest，如果以后发现这个老程序有侵入系统的问题，马上修改这个manifest就可以解决问题。<br>&nbsp;&nbsp;&nbsp;&nbsp; 你可能要说，如果程序试图修改自己的manifest呢？这个可以在操作系统内核进行验证，没哪个程序能修改Windows内核吧？就是这个道理，如果manifest的checksum与以前的不一样，那就需要一些用户手动验证。</p><img src ="http://www.cppblog.com/sunicdavy/aggbug/92827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/sunicdavy/" target="_blank">战魂小筑</a> 2009-08-10 17:57 <a href="http://www.cppblog.com/sunicdavy/archive/2009/08/10/92827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>