写给三十岁以上的程序员

本人80年生,这一般是个适合开始的,也是个容易总结的年份,总结就是一种创新,所以我的话就多。

中国IT圈,是有传统特色的,你会找到江湖的味道。那么,混不好的话你就可能挨几刀或者走火入魔。

做技术的你真的需要职业规划,个人战略,运气,勤劳,魄力,以及聆听自己的心声。

切记一,江湖上的传说都留给别人吧,富二代,财团,那些争夺虚名的胜利者。

切记二,心静了,也不能滥学,不然你会被半浅不深的技术淹死,半熟不热的噎死,千万别“以苦做舟”,没兴趣,不快乐的话,快点闪人,时间和精力有限,别等开进了胡同倒不出车。—-入魔的

我的一个同学R,做开发工作5年时,就嘴上总挂着转行,不想搞开发。心理的呼唤,没有理,况他也不忍失掉机会成本,因为不做技术,去新行业又拿不到高薪,由奢入俭难,然后先干着,一晃几年又过去了,嘴上又挂着转行,但这时可能就是被外界种种逼的。—-挨刀的

如果你没有保持对新技术的敏感

如果你没有对技术掌握的成就感,好奇心

如果你没有自己家里的开发环境和实验码田

如果你没有技术微博和一箱子的书和案头的手册

如果你没有最想深入了解的技术方向

如果你没有无数个深夜面着电脑搞这搞那儿,忘记吃饭和睡觉

如果你没有承担40岁后失业勇气

如果有,全有。

亲,那么恭喜你,我们进阶吧。

 

IT带来的不是多少个职位和行业,而是一个时代。虽然你30岁多了,但是你是这个时代的建设者和亲历见证者,你有权要求发声音,也应该有了担当来发声音。

一,认清大环境

中国的IT业还不是个完全市场导向的,因为这是共产主义国家。

传统行业的信息化和新行业相比,后者才是IT圈新贵们蛰伏的乐土,但是急功近利。

程序员想搞科研去大学,研究所,少在老板面前晃悠,等你真去了说不定,他主动找上你,在你眼前晃悠了。但我劝大家,IT只是工具和手段,应用科学需求量总是比理论高,就是个金字塔型的下端之于上端。

二,认清生存元素

好的IT公司是应该有自己的擅长的领域并且能留人。就像天龙八部里的少林,藏经阁里的扫地僧。

那些领域更适合你

三,认清自己的风格

你是哪类程序员,喜欢静,宅,喜欢看百家讲坛多过于娱乐频道。

白天求生存,夜晚求发展

人们从他的身上感觉到一股力量。

以上是几年前写的,现在我在一个不以技术为主的,以业务实体更看重的公司(甲方是国企),这样的确是比较稳定的,对技术人员也很尊重,(一个有老程序员较多的公司坏不了多少),我放弃许多挑战自己的骨气和机会,只为稳定,也不知对不对,希望这观点别太深的影响你的判断。

nginx+redis应用服务架构搭建

事实上,两个东东功能独立。nginx作为开源的web服务器,可以用做反向代理等。而redis说白了就是一个内存数据库,存储键值对,可以多节点部署在多个物理机做为应用层,可以集群方式自动管理。可以不用重启,灵活增删节点等。
此处放在一起是因为工作中整理需要。当然,你可以分开阅读或借鉴。
前提:
CentOS6.5 x86_64
一,基础软件:有些并不是必须的补丁。
先用yum install -y XXX,如何需配置本地安装源有本站另外文档介绍。
如果没有yum那必须要有安装光盘的Packages文件夹了,里面是配套的软件包。用rpm -ivh XXX.rpm即可。
gcc的依赖如下:

cloog—–ppl
cpp—–mpfr
g++(gcc-c++)

libstdc++-devel
jdk

使用的openjdk的版本

把起作用的路径先设置成HOME路径,然后加入path。
如,java的默认路径是/etc/alternatives/jre_openjdk
#vi ~/.bash_profile
加入内容:
export JAVA_HOME=/etc/alternatives/jre_openjdk
export JRE_HOME=/etc/alternatives/jre
PATH=$JAVA_HOME/bin:$PATH:$HOME/bin
如下两个补丁包可以略,因为,在nginx的安装过程中也必须要源码编译安装。
PCRE
openssl-devel、pcre-devel、zlib-devel
zlib:
./configure
make
make install
ruby

libruby
ruby-libs
—-libreadline()
cd /path/ruby
./configure -prefix=/usr/local/ruby
make
make install
sudo cp ruby /usr/local/bin
事实上,用yum安装的话:yum install ruby,即可了
rubygems:

首先使用yum install rubygems来“投石问路”,就看到它所依赖的包,然后,在Packages目录里把rdoc和另一个包安装好,
最后,去网上下到了rubygems,
rubygems-1.3.7-5.el6.noarch.rpm
解压安装,成功。
没有yum的情况:
cd /path/gem
sudo ruby setup.rb
sudo cp bin/gem /usr/local/bin
gem-redis:

这是ruby和redis之间的桥,此时yum已经插手不上了。
方法一:
gem install redis –version 3.0.7
#由于源的原因,可能下载失败,就手动下载下来安装
#download地址:http://rubygems.org/gems/redis/versions/3.0.7
wget加url
方法二:
下载gem文件,在上面的url里一定会找到。
现场使用语句
gem install -l /root/tool/redis-3.0.7.gem
二,redis安装和运维:
安装集群:
tar -zxvf redis-3.0.7.tar.gz
mv redis-3.0.7 /usr/local/redis3.0.7
cd /usr/local/redis3.0.7
make
make install
cp /usr/local/redis-3.0.7/src/redis-trib.rb /usr/local/bin/
mkdir -p /usr.local/cluster
cp /usr/local/redis-3.0.7/redis.conf /usr.local/cluster
cd /usr.local/cluster
mkdir 7000
mkdir 7001
mkdir 7002
1)启动节点,或说实例,在/usr.local/cluster/
现行配置redis.conf如下:
daemonize yes
port 9001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
cd 7000;redis-server /opt/redis/conf/redis.conf > redis-0.log 2>&1 &
cd ../7001;redis-server /opt/redis/conf/redis.conf > redis-1.log 2>&1 &
cd ../7002;redis-server /opt/redis/conf/redis.conf > redis-2.log 2>&1 &
2)构建集群关系
#redis-trib.rb的create子命令构建
#–replicas 则指定了为Redis Cluster中的每个Master节点配备几个Slave节点
#节点角色由顺序决定,先master之后是slave(为方便辨认,slave的端口比master大1000)
—单机情况下:
redis-trib.rb create –replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002
—双机情况下:
redis-trib.rb create –replicas 1 130.1.2.11:7000 130.1.2.11:7001 130.1.2.11:7002 130.1.2.12:7000 130.1.2.12:7001 130.1.2.12:7002
3)检测集群工作情况
  #redis-trib.rb的check子命令构建
#ip:port可以是集群的任意节点
redis-trib.rb check 1 130.1.2.11:7000
结果是:
[OK] All nodes agree about slots configuration.
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
说明运行正常了。或者redis-cli -c -p,-h 10.0.0.1 -p 后ping/PONG
现场抓图:
技巧:
重改配置时常用语句:
cd ../7002/;rm nodes.conf -f;mv redis.conf redis.conf.v0
三,nginx安装
版本:
在/root/tool/下进行解压和编译安装。
现场最终起作用的语句:
./configure –with-pcre=pcre-8.12 –with-openssl=openssl-1.0.1c –with-zlib=zlib-1.2.8 –with-poll_module –prefix=/home/linux/nginx/nginx-1.9.4/run –with-stream
make;make install
把安装路径加入到path中,export NGINX_HOME,参考上面java安装。即/home/linux/nginx/nginx-1.9.4/run。
配置文档如下:在/home/linux/nginx/nginx-1.9.4/run/conf下面,名为nginx.conf.
删除http节,如果发现已经存在stream节,即把同名的节替换即可。
stream {
    server {
        listen 80;
        proxy_pass app;
    }
    upstream app {
        server 130.1.2.11:4442;
        server 130.1.2.12:4442;
    }
    server {
        listen 81;
        proxy_pass appp;
    }
    upstream appp {
        server 130.1.2.11:6666;
        server 130.1.2.12:6666;
    }
    server {
        listen 82;
        proxy_pass apppp;
    }
    upstream apppp {
        server 130.1.2.11:4433;
        server 130.1.2.12:4433;
    }
}
.nginx的启动
nginx -c /home/linux/nginx/nginx-1.9.4/run/conf/nginx.conf
重启命令 nginx -s reload
关闭
  1.从容停止:kill -QUIT nginx主进程号 (注释:进程号查询方法;ps -ef|grep nginx 看master进程号)
  2.快速停止:kill -TERM nginx主进程号
  3.强制停止:pkill -9 nginx
测试端口是否开放,当然先装好nc工具
nc -z -w 1 127.0.0.1 8883
可以快速开放一个tcp端口,相当于建立一个socket server:
nc -l 8884
用这个命令开放某个端口穿越防火wall
iptables -I INPUT -p tcp –dport 82 -j ACCEPT
iptables -L -n | grep 82
service iptables save
四,业务程序:

yum本地安装源配置

使用yum要具备工具,所以,安装好这个包很重要。
在Linux下有了它,就像是光夫有机器猫,大圣有了金箍棒。
在/etc/yum.repo.d/目录下,一般会有四个文件。
…………CentOS_Base.repo——-网络源,要想在无网络状态下就要禁用它,重命名,加上.bak
…………CentOS_Media.repo—–这个就是光盘或挂载的文件了,修改它。
在baseurl 中修改第2个路径为/mnt/cdrom(即为光盘挂载点),注意,挂载点下面要有repodata/repomd.xml(这个是纽带)
将enabled=0改为1
然后保存,#yum update后就可以使用了。
注意,还包含一些很长文件名的文件。所以,即使没有光盘,可以把xml和长文件名文件拷出来放到系统内文件夹中。

道可道,非常道

老子的这六个字,想传达什么?我大胆的扯一下。
首先,它表达了,实践。因为道的部首是走。行走中悟,即是道。事实上,这已经足够,不必多言了。
任你大道无形,随你百般变化。非常道,此时就是指:不是永远不变的。
其次,它让大家意识到,道即变化和其中规律,注重规律,以及规律的规律,以及那些无法言语的规律。总结出来的规律的规律,才是不普通的道。此为“非常道”的第二个变种理解。
最后就是,还有四种字面上的硬解析了。百度转载而来。再加上,名可名,非常名的后半句。
(1):圣人之道是可以行走的,但并非是唯一不变的道路;真正的名声是可以去求得的,但并非一般人一直追求的名声。
(2):道是可以被说出来的,说出来的却不是永恒的道,万物是可以去命名的,但却不是万物永恒的名。——-同于本人归结的上面的实践要求
(3):道本身也是遵循着一定的“道”,但这个“道”并不是平时可以观测到的最基本的道,虽然对这个“道”也确实存在着,但不是以现有的道的维度所能解释的。——-让人们容易走火入魔
(4):道是道,不是道也是道。名是名,不是名也是名。两者同出,异名同谓。———得道即可得名,得名自然得道
惭愧仅扯出6条不同的分支,聪慧的人,估计36个心得都不在话下。老子,NB

windows核心编程(第5版)读书笔记一

第一章节 错误处理
几乎所有的windows API返回值都是下列之一:
VOID——不会失败,失败了骚扰bill gates去,
BOOL——不用说了吧,
HANDLE—失败则是NULL,当然有时是-1,
PVOID—–失败是NULL,成功就是指针喽,
LONG/DWORD—-要看具体的上下文环境了。
当调用失败,返回值会先指出已经发生错误。所以要先判断返回值。然后,使用GetLastError()来得到详细的错误提示。返回值是dword类型的,要得到描述,加入WinError.h.
技巧一:在监视中,$err,hr,就会看到调用的API错误的内容。
技巧二:使用VS的IDE小工具,error lookup
只你自己开发的模块想返回不一样的error时,可以使用SetLastError(DWORD)来写入,当然,错误代码要像点样,即32位中的29位要必须为1.而0是给系统用的。
第二章节 字符和字符串的处理
VC6——ANSI,DBCS——-/Zc:wchar_t(这个选项就会有定义wchar_t这个数据类型)
VS201X———–ANSI,UNICODE(指的是UTF-16)
事实上,typedef unsigned short wchar_t;
WinNT.h中统一了类型的名称。
TEXT(param)在unicode宏定义下,在param前加了L前缀。
所以,TCHAR也是个宏,可以配合TEXT(),_T() 来一起变脸。
unicode阵营的后缀或关键字母:
w—wide
L—-
ansi阵营的后缀或关键字母:
a—ansi
中性函数:或会变脸的,应用在两种编码下都可以编译场景,加入TChar.h配合String.h
_tcslen()会变脸成wcslen或strlen
C库的新版本的安全系列函数
1)字符串函数:加入StrSafe.h
_tcs拼加后面的选项即可cpy/cat/再拼接_s后才是安全字符串函数。第二参数为要处理的字符长度,用_countof宏(stdlib.h) 来得出字符数最好,注意不是字节数哟.
StringCch为前缀的也是安全函数。
注意:
使用微软包装的安全函数代替C库函数,好处是即时发现内存操作的异常,但有时也可能会出现“Debug Assertion Failed”对话框。当然要是debug模式下,当然也有办法屏了它,用release或定义InvailidParameterHandler函数,然后注册它,再程序运行开头加入个宏:_CrtSetReportMode(_CRT_ASSERT,0);
判断返回值必须等于宏S_OK,当不是这个值时必须要检查字符串的操作。
2)安全缓冲区函数:加入CrtDefs.h
memcpy_s——–wmemcpy_s
memmove_s——-wmemmove_s
第三章节 内核对象
有SECURITY_ATTRIBUTES结构为参数的生成才是内核对象,区别于GDI和其它的对象。
所以这也揭露了内核对象的本质是—-结构。而句柄则是—–由系统管理着的内存地址
CloseHandle()函数详析:
工作步骤:
1,验证自己主调进程中的句柄表,是否有权访问此句柄。如果有效,则获得内核对象的数据结构地址。
2,把内核对象结构使用计数减1,如果是0了,则销毁。
注意:
如果参数是无效的句柄,CloseHandle返回false,GetLastError返回ERROR_INVALD_HANDLE。如果在调试,则出现0xC0000008的异常抛出。
当函数返回前,清除当前进程的句柄表,所以以后代码不能再使用此句柄了。
当用变量保存过句柄的话,应该设置为NULL。
任务管理器是可以查看程序中的进程句柄表。
跨进程边界共享内核对象—略

windows核心编程(第5版)读书笔记二

第四章节 进程
进程内核对象在创建的时候总会处于未激发,无信号状态,但当进程终止时,系统自动会让进程对象变成激发状态,并且会永远保持这种状态。即回不到未激发状态。
C库会根据三个维度选择入口点函数:
编码,运行模式,运行环境
_tWinMain(WinMain)
wmainCRTStartup
_tmain(wMain)
_tmain(Main)
mainCRTStartup
wWinMainCRTStartup
WinMainCRTStartup
_tWinMain(wWinMain)
编码
ANSI
UNICODE
UNICODE
ANSI
ANSI
UNICODE
ANSI
UNICODE
运行模式
GUI
CUI
CUI
CUI
CUI
GUI
GUI
GUI
运行环境
WIN16
WIN32
WIN16
WIN16
WIN32
WIN32
WIN32
WIN16
在VC自有的C运行库的源代码中,crtexe.c中可以找到以上win16四个函数的源代码。
这些启动函数或者说入口函数的作用是:
1)获取指向新进程的完整命令行的一个指针
2)获取指向新进程的环境变量的一个指针
3)初始化C运行库的全局变量。如果包括了StdLib.h,就可以访问这些全局变量了。
4)初始化内存分配和IO底层
5)调用所有全局和静态C++类对象的构造函数。
系统接管,加载exe,dll到进程的一个地址空间(与链接器有关了),把这个地址返回给第一个入口函数的参数,即实例句柄。
下面可以玩这个句柄了,GetModuleFileName().
如果,你忘记实例句柄了,或没没放到全局里,不过没关系,可以用GetModuleHandle(param).参数可以是一个路径,最好是程序里用到的某个dll,要么,param就是NULL,这样就会得到运行着的当前进程的实例句柄。
命令行和环境变量,最好不要用C运行库初始化后的内容,万一时机没对,还没初始化你就读了,会出问题,所以window有厚道的API。GetCommandLine(),C运行库都在用,你凭啥找事儿,对吧。
技巧一:配合CommandLineToArgvW(GetCommandLine(),&nNum),可以得到友好的命令行参数。
这个配置和系统—》高级系统设置—》系统变量的内容是一致的。
入口点函数完后,就是进程的后事了,包括:
1)C运行库接管,调用自己的exit
2)调用_onexit()此前注册的任何一函数,假如你注册了的话。
3)调用所有全局和静态C++类对象的析构函数
4)如果有DEBUG则可以生成内存泄漏报告,可以深入去研究下。
5)C运行库来调用操作系统的ExitProcess函数,把入口点返回值以参数传入,即退出代码。这样系统就会杀死进程了,此函数返回值是void,它通知OS了,就应该无声息的over了。
注意,有时入口点返回,而有时线程可以调用ExitProcess和TerminalPorcess。
入口函数中显示使用ExitThread的函数,会让主线程退出,但如果其它线程还在工作呢?进程就不会退出,造成僵尸进程的凶手。
入口函数中显示使用ExitProcess的函数,会让C运行库函数没有执行清理资源的机会。
所以,最保险就是永远不显示的调用ExitX之类的函数。
更NB和危险的函数还有,那就是TerminalProcess,它厉害在它可以在某线程里被用,去干掉自己和别人的进程。

进程当前目录
这里要注意,因为,进程下的线程是有能力改写进程的当前目录,这也包括子进程。所以,要注意。
线程会通过GetCurrentDirectory()和SetCurrentDirectory()来存取路径。
做为进程,可以使用GetFullPathName()来看看现在的路径或者根据驱动器去环境变量里找到某路径。

windows核心编程(第5版)读书笔记三

第六章节 线程基础
创建线程,要使用_beginthreadex来代替WAPI提供的CreateThread。因为,要从编译器角度来创建。从用户角度至少看起来没有依赖OS。但事实上,里面还是用了CreateThread.
同样,杀线程,使用_endthreadex.
注:用以上两个库函数的原因是,因为,如果你用了signal函数,那么就要用_end函数来清理资源,可是那样,你就画不圆上下文了。同时使用时要注意有EX来标识的,因为存在着旧的弃用的函数。
CloseHandle是可以传已经被清理的或伪句柄的,只是它会返回false,并且对error置成ERROR_INVALID_HANDLE。
TerminalThread是异步的,只是发信号。要确定被杀的线程死了,要用WaitForSingleObject,向其传递线程句柄来守候。原理就是,线程的内核对象,当引用计数减为0时,会变成激发状态,有信号状态。
GetExitCodeThread是检查线程退出代码的。如果线程还没有退出,返回是STILL_ACTIVE宏的值。如果已经退出,返回true,并有相应值。
微软提供的C/C++库用于本机的开发。
libCMt.lib
库的静态链接发行版本
libCMtD.lib
库的静态链接调试版本
MSVCRt.lib
导入库,用于动态链接MSVCR80.dll(默认库)
MSVCRtD.lib
导入库,用于动态链接MSVCR80D.dll
MSVCMRt.lib
导入库,.net的托管/本机代码混合
MSVCURt.lib
导入库,.net的MSIL代码
线程句柄自获函数:
几乎所有的WAPI函数都要在第一参数传句柄的,所以,当你突然眼前一亮,想用WAPI了,这第一个参数必须难不住你呀。
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
注意:以上两函数返回的是“伪句柄”
原因:
1)它们不会在进程句柄表中新建句柄,当然也不会影响引用计数。当然,CloseHandle()多释放一次,程序不死,只是它返回false。
2)它们返回的句柄要根据运行所在的进程和线程来关联。比如,在父线程中调用了,返回的句柄即使以参数传给子进程,则其指向仍然是子线程的。所以这一点有些像虚函数中的虚指针,只能意会不能言传了。
当然,有时用线程ID做些逻辑时,可以使用:
DWORD GetCurrentProcessId();
DWORD GetCurrentThreadId();
当然,如果你有了ID,你还可以换成句柄。
OpenThread(),下面示例一下转换办法并且,给出一个对进程优先级操作的技巧。
VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend)
{
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwProcessID);
     if(hSnapshot != INVALID_HANDLE_VALUE)
     {
          //walk the list of threads
          THREADENTRY32 te =  {sizeof(te)};
          BOOL fOK = Thread32First(hSnapshot, &te);
          for(; fOK; fOK = Thread32Next(hSnapshot, &te))
          {
              if(te.th32OwnerProcessID == dwProcessID)
               {
                    //主角登场
                    HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
                    //略过对hThread的判断
                    if(fSuspend)
                         SuspendThread(hThread);
                    else
                         ResumeThread(hThread);
                    CloseHandle(hThread);
               }
          }//endfor
          CloseHandle(hSnapshot);
     }
}
最后,再赠送两个函数用于获取进程,线程运行的时间。
GetProcessTimes(),GetThreadTimes()
第七章节 线程调度,优先级和关联性
线程可以自己挂起,但不能自己恢复,并且,挂几次要应该恢复几次(ResumeThread)。挂起可以在线程生成时以参数传入,也可以用SuspendThread来人工自由操作。
第八章节 用户模式下的线程同步
技巧:
原子操作的系列WAPI函数:InterLocked*
+ExchangeAdd
+Increment
+ExchangePointer
volatile关键字,用来声明,后面的变量不能被优化,要去不断从内存来读取。
进阶一段:CRITICAL_SECTION结构和EnterCriticalSection和LeaveCriticalSection
要声明个全局的CS变量,然后用前初始,用后删除。
TryEnterCriticalSection比较灵活,做人当如此,能锁定就锁定段,没有段可用时,就立刻通知调用者。
同时,也不要把初始化关键段看低,因为,能避免交给内核态就晚点交,不然,上下文切换的步骤很耗时,耗资源的。所以,给初始化传值或用Set来设置抢段的重试时间,InitializeCriticalSectionAndSpinCount(p1,p2),p1是句柄了,p2大约4000。
注意:
线程抢锁的顺序要一致,否则死锁,即在锁包锁的情况下。
关键段的使用只能在一个进程内来控制其中众线程的同步,并且不能根据时间来等待。
进阶二段:条件变量
线程想把锁释放并把自己阻塞,就使用条件变量。
注意,这时,你得玩两个内核对象才行,即条件变量,必须配合锁。
首先看看这个阻塞函数,我特喜欢微软用sleep来前缀,因为,可读性很高。体现了两层意思:1,这是阻塞的,2,这是有时间参数的,时间到了没拿到条件变量就是false.
SleepConditionVariableSRW或SleepConditionVariableCS看吧,后缀又说明了要配合的锁。够意思。
我不够意思了,不列参数,自己去查手册喽。
有了Sleep就得有Wake吧。它会使等待同一个条件变量被触发的线程得到锁并返回。然后就干活呗,但得到锁了就得释放它。但它不会同时唤醒其它正在等待同一个条件变量的线程。
要看自己的实际需要。反正也是有WakeAll*和共享锁和独占锁来设计。
第九章节 内核态用内核对象进行线程同步
进程和线程内核对象在操作系统的处理上一样设计的。见笔记二的进程描述。
本章节介绍了另外的内核对象来帮助我们玩转线程同步。
1,事件
2,可等待的计时器
3,信号量
4,互斥量
头大吧,不过,我们要想掌握它,必须用不同的维度和结构去3D它。
首先,了解基础,或者说这个是第一个维度。
前进了解了进程和线程,有信号和无信号的规则,那么,这四个对象呢,look
事件:
引用计数器
自动重置/手动重置———–初始参数方式,CreateEvent
是否被触发——————-函数控制,SetEvent,ResetEvent
手动重置事件:
被触发时:等待此事件的所有线程都是会变成可调度状态。
自动重置事件:
被触发时:等待此事件的一个线程,只有一个线程会变成可调度状态。
因为自动重置会在一个线程得到事件对象后,自动把自己变成未触发状态。系统代劳的。
可等待的计时器:
指定时间或每隔一定时间触发
引用计数器
自动重置/手工重置——-初始化方式,CreateWaitableTimer,和事件一样没有其它的设置方式
SetWaitTimer是生成了内核对象后,需要进一步应用时的必经之路。因为,创建后,计时器都是属于未触发状态。
信号量:
引用计数器
最大资源量————-池里的资源总数
当前资源数————-目前应用了资源的数量,用RealseSemaphore来递增
互斥量:
引用计数器
线程ID———–内部自己管理,当计数为1时,则用调用的当前线程ID来填充。
递归计数———是否要触发

windows核心编程(第5版)读书笔记四

第19–20章节 dll的基础和高级技术
入口点函数:DllMain()
一般用来执行一些进程,线程有关的初始化和清理工作。要么不实现它,要么实现正常,返回true,否则,dll可能就不能被使用。
注意:
区分大小写的,否则就是无用的。
隐式调用dll时,系统启动时就会用到DllMain(),而显式调用时,在LoadLibraryex中来调用。并且,切入点是DLL_PROCESS_ATTACH
当引用了dll的exe要建立个新线程时,会检查所以已经被调入进程空间的dll的DllMain。并传入DLL_THREAD_ATTACH。有一个例外就是主线程切入仍以process来通知dll.

林李之战

古有瑜亮,今有林李。
又一个奥运,又一对宿敌。真过瘾,两个人撑起男子羽毛球的春秋,曾记得还有位狂人陶菲克,无耐掉队。今天,结果变成最不重要的结果,人们只是欣赏。他们告别生涯,我们告别青春。人生啊,有几次林李大战?事实上,我也没看几次,但江湖上有他们的传说,我有本林丹的自传而己。另一半区新秀双龙战。那个丹麦小伙,竟一口流利的中文,有点像湛龙的李宗伟。但成色略逊,难称德比 。湛龙孤独着是新时代篇章的前言。

为林李高兴,为知己喝彩。
今天的关键词是什么,坚持。为老将们笑着离开吧,且让他们释然吧!放下,享受~~,只为那更长的路。

自动关闭程序屏蔽windows对话框

windows server 2012关闭无响应程序对话框?
windows server 2012不提示是否要联机查找解决方案对话框?
只要干脆利落的自动关闭程序。那么follow me.有几点可以试试。
  • 关闭无响应程序
在Vista和Windows 7及以上的OS上,参照以下方法:
■在开始运行中输入regedit并回车
■定位到HKEY_CURRENT_USER\Control Panel\Desktop
■设置AutoEndTasks键值为1,如果没有可以手动创建一个名为 AutoEndTasks 类型为REG_SZ值为1的表项。
■WaitToKillAppTimeout是超时等待时间,默认值12000,这个值在很多网站上建议修改短一点,这里不推荐,最好不要改。因为程序的运行是综合的,影响超时的时间会很多,太短的超时时间可能会带来一些“莫名其妙”的问题。
如确认修改WaitToKillAppTimeout,请统一修改:
HKEY_CURRENT_USER\Control Panel\Desktop
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
下的WaitToKillAppTimeout,比如1000,2000均可以。
  • 关闭问题报告:
控制面板–系统和安全—操作中心—问题报告设置
点选“从不检查解决方案(不推荐)”
UAC设置方法/步骤:
你可以完全关闭UAC,在控制面板–系统和安全—操作中心中。也可以通过下面的步骤来设置它。(但要想干脆利落,你知道咋办)
1,点击控制面板,选择所有控制面板项,点击用户帐户
2,点击“更改用户账户控制设置”弹出计算机用户安全通知设置,始终通知(高):这是最安全的设置,收到通知后,你应该先仔细阅读每个对话框中的内容,然后才允许对电脑进行更改。
3,始终通知(中):如果系统允许对 Windows 设置进行更改而不通知你,则表明这种更改是安全的。但是,Windows附带的某些应用可以将命令或数据传递给它们,恶意软件可能会利用这一点,使用这些应用在电脑上安装文件或更改设置。应该始终小心允许在电脑上运行的应用。
4,始终通知(中低):与“仅当应用尝试更改计算机时通知我”相同,但是不会降低桌面亮度。如果选择此选项,则其他应用可能会影响用户帐户控制对话框的可视外观。这是一个安全风险,尤其是你的电脑上存在恶意软件时。
5,从不通知:这是最不安全的设置。将用户帐户控制设置为从不通知时,你便有效地关闭了用户帐户控制。这会使得你的电脑面临潜在的安全风险,这个设置一般在虚拟机练习时候设置
  • 关闭“已停止工作”对话框
 最近发现一个很早以前的程序出现了兼容性问题。程序有检测机制,发现异常退出可以自动重启。但是这次没有重启成功。操作系统是Windows 2008,以前用的操作系统是Windows 2003,在2003上就没有该问题。
后来发现2008和2003的错误报告机制不同。2008下,遇到程序崩溃会弹出一个错误提示对话框,需要手工关闭,程序才能退出。

临时解决问题的方法就是想办法关闭这个对话框。Windows有很多错误提示框,关了一个还会出现另外一个。
下面的方法可以关闭以下的几个对话框不再出现:
xxx已停止工作
xxx-应用程序错误
xxx-未找到调试器

需要修改三个地方:
1.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
在.NETFramework上点击右键-》新建-》DWORD(32-位)值-》
名称:DbgJITDebugLaunchSetting
数据:1
2.HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting 修改两个值(修改第一个值也可退出,但是退出时间较长,测试环境需要1分钟左右,应该是在收集错误信息)
名称:DontShowUI    数据:1

名称:Disabled      数据:1
  • 关闭错误报告
下面这句在开始—-运行中键入,效果是关闭server的错误报告,适用于2008 server。可以用/query,/详细,/摘要,/summary来替换如下的禁用。
serverWerOptin /禁用
我发现了另外引导的 MSDN如何从用户可以抑制嵌入式系统上发生的系统和应用程序的错误信息。注册表中的位置是在以下默认情况下,该数值数据为0,我们应该将其更改为2设置为不可见的所有邮件。
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Windows\ErrorMode.
  • XP关闭无响应方案:
首先打开注册表:在[开始]–>[运行]–>键入[Regedit];  然后找到相关项目按照以下步骤进行设置:  左侧列表中依次展开,找到[HKEY_CURRENT_USER\ControlPanel\Desktop],这个就是设置软件无响应时的选项。将里面AutoEndTasks的数值从0修改为1就是让系统自动关闭无响应的软件。